I am a little bit new to Docker and deployment cycle.
I have Django application that we would like to deploy with uWSGI to docker container. Actually the deploy worked perfectly for a few weeks, but now it soundly report error...
Error seam to be with cryptography package:
build/temp.linux-x86_64-3.6/_openssl.c:52862:10: warning: conversion to 'long unsigned int' from 'long int' may change the sign of the result [-Wsign-conversion]
build/temp.linux-x86_64-3.6/_openssl.c: In function '_cffi_f_SSL_set_options':
build/temp.linux-x86_64-3.6/_openssl.c:52895:14: warning: conversion to 'long int' from 'long unsigned int' may change the sign of the result [-Wsign-conversion]
{ result = SSL_set_options(x0, x1); }
^~~~~~~~~~~~~~~
build/temp.linux-x86_64-3.6/_openssl.c:52895:14: warning: conversion to 'long unsigned int' from 'long int' may change the sign of the result [-Wsign-conversion]
error: command 'gcc' failed with exit status 1
----------------------------------------
Command "/usr/local/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-dg_tg9pa/cryptography/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-my98rwq4/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-dg_tg9pa/cryptography/
The command '/bin/sh -c pip install --no-cache-dir -r requirements.txt' returned a non-zero code: 1
ERROR: Job failed: exit code 1
Our docker file looks like
FROM python:3-alpine
ENV PYTHONUNBUFFERED 1
WORKDIR /usr/src/app
RUN apk add --no-cache gcc mailcap python3-dev build-base linux-headers pcre-dev postgresql-dev libffi-dev libressl-dev
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
As I mention the docker file and requirement.txt hasn't change between success build and failed one. (What is the most strange to me...)
The only think I could think is that command
FROM python:3-alpine
is taking the different version of alpine...
Is this possible? What could be wrong? How to fix it?
Alpine is a headache distro for most Python packages that ship C/C++ extensions (code written in C/C++ that is compiled to a shared object and loaded in Python via a foreign function library). The reason for that is that is PEP 513 which portability definition between Linux distros, manylinux1, is based on glibc/glibcxx. Since Alpine uses musl libc, no manylinux1 compatible wheel can be installed on Alpine. So when you issue pip install cryptography, the wheel with the compiled extensions is filtered and pip tries to build the package with all the C extensions from source.
installing with the system package manager
This is the preferred way and was mentioned by @GracefulRestart in the comments; use it if you don't need the bleeding edge version of the package. Install it with apk:
$ apk add py-cryptography
installing with pip
Should you need the bleeding edge version, you can try building it from source by installing with pip.
Preparing the build environment
You will need the compiler and libraries with header files: musl, OpenSSL, libffi and Python itself:
$ apk add gcc musl-dev libffi-dev openssl-dev python3-dev
Building
$ pip install pkgname
hides the build log by default. To see the complete build log, add -vvv to increase verbosity. (Optional) Also, you can explicitly prohibit installing manylinux1 wheels by adding -
-no-binary=pkgname
so the build from source will be enforced.
$ pip install cryptography -vvv --no-binary=cryptography