I'm trying to build an image based on the official python:3.8-alpine
and include the python uvloop
package.
When I build, it works on my machine(tm), but trying to build the same Dockerfile on our build system fails.
Both systems are running Linux, but my local machine is moderately up-to-date, while the build-system is ancient (both kernel and Docker), more details at bottom.
This is a small Dockerfile where I can reproduce the issue:
FROM python:3.8-alpine3.14
RUN apk add --update build-base
RUN pip install uvloop==0.16.0
Which locally outputs:
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM python:3.8-alpine3.14
---> 252da3e451af
Step 2/3 : RUN apk add --update build-base
---> Running in c7178804aa11
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/20) Installing libgcc (10.3.1_git20210424-r2)
(2/20) Installing libstdc++ (10.3.1_git20210424-r2)
(3/20) Installing binutils (2.35.2-r2)
(4/20) Installing libmagic (5.40-r1)
(5/20) Installing file (5.40-r1)
(6/20) Installing libgomp (10.3.1_git20210424-r2)
(7/20) Installing libatomic (10.3.1_git20210424-r2)
(8/20) Installing libgphobos (10.3.1_git20210424-r2)
(9/20) Installing gmp (6.2.1-r0)
(10/20) Installing isl22 (0.22-r0)
(11/20) Installing mpfr4 (4.1.0-r0)
(12/20) Installing mpc1 (1.2.1-r0)
(13/20) Installing gcc (10.3.1_git20210424-r2)
(14/20) Installing musl-dev (1.2.2-r3)
(15/20) Installing libc-dev (0.7.2-r3)
(16/20) Installing g++ (10.3.1_git20210424-r2)
(17/20) Installing make (4.3-r0)
(18/20) Installing fortify-headers (1.1-r1)
(19/20) Installing patch (2.7.6-r7)
(20/20) Installing build-base (0.5-r2)
Executing busybox-1.33.1-r3.trigger
OK: 202 MiB in 55 packages
Removing intermediate container c7178804aa11
---> f00115e6eb8f
Step 3/3 : RUN pip install uvloop==0.16.0
---> Running in 40c337f3d5d5
Collecting uvloop==0.16.0
Downloading uvloop-0.16.0.tar.gz (2.1 MB)
Building wheels for collected packages: uvloop
Building wheel for uvloop (setup.py): started
Building wheel for uvloop (setup.py): finished with status 'done'
Created wheel for uvloop: filename=uvloop-0.16.0-cp38-cp38-linux_x86_64.whl size=1472862 sha256=82504601e2b81a993671497bd2a8eb0c6d0e15acc037c2d45a5fce70584bcd99
Stored in directory: /root/.cache/pip/wheels/4b/be/00/02d65fc293a0a2f7578d274ea90b5e64ed510ff75b4b8e583a
Successfully built uvloop
Installing collected packages: uvloop
Successfully installed uvloop-0.16.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
Removing intermediate container 40c337f3d5d5
---> 7de1a927568f
Successfully built 7de1a927568f
Running the same build on our build system gives me:
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM python:3.8-alpine3.14
---> 252da3e451af
Step 2 : RUN apk add --update build-base
---> Running in e7629fc667aa
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/20) Installing libgcc (10.3.1_git20210424-r2)
(2/20) Installing libstdc++ (10.3.1_git20210424-r2)
(3/20) Installing binutils (2.35.2-r2)
(4/20) Installing libmagic (5.40-r1)
(5/20) Installing file (5.40-r1)
(6/20) Installing libgomp (10.3.1_git20210424-r2)
(7/20) Installing libatomic (10.3.1_git20210424-r2)
(8/20) Installing libgphobos (10.3.1_git20210424-r2)
(9/20) Installing gmp (6.2.1-r0)
(10/20) Installing isl22 (0.22-r0)
(11/20) Installing mpfr4 (4.1.0-r0)
(12/20) Installing mpc1 (1.2.1-r0)
(13/20) Installing gcc (10.3.1_git20210424-r2)
(14/20) Installing musl-dev (1.2.2-r3)
(15/20) Installing libc-dev (0.7.2-r3)
(16/20) Installing g++ (10.3.1_git20210424-r2)
(17/20) Installing make (4.3-r0)
(18/20) Installing fortify-headers (1.1-r1)
(19/20) Installing patch (2.7.6-r7)
(20/20) Installing build-base (0.5-r2)
Executing busybox-1.33.1-r3.trigger
OK: 202 MiB in 55 packages
---> 477c9cd3c00a
Removing intermediate container e7629fc667aa
Step 3 : RUN pip install uvloop==0.16.0
---> Running in 435574c7bfc8
Collecting uvloop==0.16.0
Downloading uvloop-0.16.0.tar.gz (2.1 MB)
Building wheels for collected packages: uvloop
Building wheel for uvloop (setup.py): started
Building wheel for uvloop (setup.py): finished with status 'error'
ERROR: Command errored out with exit status 1:
command: /usr/local/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/setup.py'"'"'; __file__='"'"'/tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-rd6i_1u9
cwd: /tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/
...
Complete output (235 lines):
running install
running build
running build_py
creating build/lib.linux-x86_64-3.8
creating build/lib.linux-x86_64-3.8/uvloop
copying uvloop/__init__.py -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/_noop.py -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/_testbase.py -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/_version.py -> build/lib.linux-x86_64-3.8/uvloop
running egg_info
writing uvloop.egg-info/PKG-INFO
writing dependency_links to uvloop.egg-info/dependency_links.txt
writing requirements to uvloop.egg-info/requires.txt
writing top-level names to uvloop.egg-info/top_level.txt
reading manifest file 'uvloop.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*' found under directory 'vendor/libuv/.git'
warning: no previously-included files matching '*' found under directory 'vendor/libuv/docs'
warning: no previously-included files matching '*' found under directory 'vendor/libuv/img'
adding license file 'LICENSE-APACHE'
adding license file 'LICENSE-MIT'
writing manifest file 'uvloop.egg-info/SOURCES.txt'
copying uvloop/cbhandles.pxd -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/cbhandles.pyx -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/dns.pyx -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/errors.pyx -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/loop.c -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/loop.pxd -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/loop.pyi -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/loop.pyx -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/lru.pyx -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/pseudosock.pyx -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/py.typed -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/request.pxd -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/request.pyx -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/server.pxd -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/server.pyx -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/sslproto.pxd -> build/lib.linux-x86_64-3.8/uvloop
copying uvloop/sslproto.pyx -> build/lib.linux-x86_64-3.8/uvloop
creating build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/async_.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/async_.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/basetransport.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/basetransport.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/check.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/check.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/handle.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/handle.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/idle.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/idle.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/pipe.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/pipe.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/poll.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/poll.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/process.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/process.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/stream.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/stream.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/streamserver.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/streamserver.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/tcp.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/tcp.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/timer.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/timer.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/udp.pxd -> build/lib.linux-x86_64-3.8/uvloop/handles
copying uvloop/handles/udp.pyx -> build/lib.linux-x86_64-3.8/uvloop/handles
creating build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/__init__.py -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/compat.h -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/consts.pxi -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/debug.h -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/debug.pxd -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/flowcontrol.pxd -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/fork_handler.h -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/python.pxd -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/stdlib.pxi -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/system.pxd -> build/lib.linux-x86_64-3.8/uvloop/includes
copying uvloop/includes/uv.pxd -> build/lib.linux-x86_64-3.8/uvloop/includes
running build_ext
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... ./install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... no
checking whether make supports nested variables... no
checking build system type... x86_64-pc-linux-musl
checking host system type... x86_64-pc-linux-musl
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking whether make supports the include directive... no
checking dependency style of gcc... none
checking for gcc way to treat warnings as errors... -Werror
checking if gcc supports __attribute__(( visibility("default") ))... yes
checking if gcc supports -fvisibility=hidden... yes
checking if gcc supports -fno-strict-aliasing flag... yes
checking if gcc supports -g flag... yes
checking if gcc supports -std=gnu89 flag... yes
checking if gcc supports -Wall flag... yes
checking if gcc supports -Wextra flag... yes
checking if gcc supports -Wno-long-long flag... yes
checking if gcc supports -Wno-unused-parameter flag... yes
checking if gcc supports -Wstrict-prototypes flag... yes
checking for ar... ar
checking the archiver (ar) interface... ar
checking how to print strings... printf
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/x86_64-alpine-linux-musl/bin/ld
checking if the linker (/usr/x86_64-alpine-linux-musl/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 98304
checking how to convert x86_64-pc-linux-musl file names to x86_64-pc-linux-musl format... func_convert_file_noop
checking how to convert x86_64-pc-linux-musl file names to toolchain format... func_convert_file_noop
checking for /usr/x86_64-alpine-linux-musl/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for a working dd... /bin/dd
checking how to truncate binary pipes... /bin/dd bs=4096 count=1
checking for mt... no
checking if : is a manifest tool... no
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... yes
checking if gcc static flag -static works... yes
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/x86_64-alpine-linux-musl/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking whether make supports nested variables... (cached) no
checking whether gcc is Clang... no
checking whether pthreads work with -pthread... yes
checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE
checking whether more special flags are required for pthreads... no
checking for PTHREAD_PRIO_INHERIT... yes
checking for library containing dlopen... none required
checking for library containing kstat_lookup... no
checking for library containing gethostbyname... none required
checking for library containing perfstat_cpu... no
checking for library containing clock_gettime... none required
checking for library containing sendfile... none required
checking for library containing socket... none required
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking sys/ahafs_evProds.h usability... no
checking sys/ahafs_evProds.h presence... no
checking for sys/ahafs_evProds.h... no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating libuv.pc
config.status: executing depfiles commands
config.status: error: in `/tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/build/libuv-x86_64':
config.status: error: Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. Try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).
See `config.log' for more details
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/setup.py", line 283, in <module>
setup(
File "/usr/local/lib/python3.8/site-packages/setuptools/__init__.py", line 153, in setup
return distutils.core.setup(**attrs)
File "/usr/local/lib/python3.8/distutils/core.py", line 148, in setup
dist.run_commands()
File "/usr/local/lib/python3.8/distutils/dist.py", line 966, in run_commands
self.run_command(cmd)
File "/usr/local/lib/python3.8/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "/usr/local/lib/python3.8/site-packages/setuptools/command/install.py", line 61, in run
return orig.install.run(self)
File "/usr/local/lib/python3.8/distutils/command/install.py", line 545, in run
self.run_command('build')
File "/usr/local/lib/python3.8/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "/usr/local/lib/python3.8/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "/usr/local/lib/python3.8/distutils/command/build.py", line 135, in run
self.run_command(cmd_name)
File "/usr/local/lib/python3.8/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "/usr/local/lib/python3.8/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "/usr/local/lib/python3.8/site-packages/setuptools/command/build_ext.py", line 79, in run
_build_ext.run(self)
File "/usr/local/lib/python3.8/distutils/command/build_ext.py", line 340, in run
self.build_extensions()
File "/tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/setup.py", line 242, in build_extensions
self.build_libuv()
File "/tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/setup.py", line 221, in build_libuv
subprocess.run(
File "/usr/local/lib/python3.8/subprocess.py", line 516, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['./configure']' returned non-zero exit status 1.
----------------------------------------
ERROR: Command errored out with exit status 1: /usr/local/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/setup.py'"'"'; __file__='"'"'/tmp/pip-install-r567wifh/uvloop_e0dbbafa75f14a38841af2a014583bfc/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-g_uzij40/install-record.txt --single-version-externally-managed --compile --install-headers /usr/local/include/python3.8/uvloop Check the logs for full command output.
The command '/bin/sh -c pip install uvloop==0.16.0' returned a non-zero code: 1
The above output sliced in the middle to pass the 30k char limit on posts.
Easiest way to perform the build (no need to create a Dockerfile):
echo -e "FROM python:3.8-alpine3.14\nRUN apk add --update build-base\nRUN pip install uvloop==0.16.0" |docker build --no-cache -
$ uname -a |awk '{print $3}'
5.11.0-7620-generic
$ docker version
Client: Docker Engine - Community
Version: 20.10.7
API version: 1.41
Go version: go1.13.15
Git commit: f0df350
Built: Wed Jun 2 12:00:45 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.7
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: b0f5bc3
Built: Wed Jun 2 11:58:56 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.9
GitCommit: e25210fe30a0a703442421b0f60afac609f950a3
runc:
Version: 1.0.1
GitCommit: v1.0.1-0-g4144b63
docker-init:
Version: 0.19.0
GitCommit: de40ad0
$ uname -a |awk '{print $3}'
4.4.0-194-generic
$ docker version
Client:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built: Thu Aug 18 05:33:38 2016
OS/Arch: linux/amd64
Server:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built: Thu Aug 18 05:33:38 2016
OS/Arch: linux/amd64
After further googling, it turns out that the issue here is that newer versions of Alpine Linux (3.14+) requires Docker 20.10.0 or higher.
Downgrading Alpine to 3.13 properly builds.
Given that Ubuntu 16.04 on the build system is EOL since April 2021, I'll aim at having it upgraded rather than pinning old version of Alpine for the build.