首页 > 解决方案 > Docker 构建在两个系统之一上失败

问题描述

我正在尝试基于官方构建图像python:3.8-alpine并包含pythonuvloop包。

当我构建时,它可以在我的机器(tm)上运行,但是尝试在我们的构建系统上构建相同的 Dockerfile 失败。
两个系统都在运行 Linux,但我的本地机器是最新的,而构建系统是古老的(内核和 Docker),更多细节在底部。

这是一个小的 Dockerfile,我可以在其中重现该问题:

FROM python:3.8-alpine3.14
RUN apk add --update build-base
RUN pip install uvloop==0.16.0

成功构建

本地输出:

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

构建失败

在我们的构建系统上运行相同的构建给了我:

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

上面的输出在中间切片以通过帖子的 30k 字符限制。

复制

执行构建的最简单方法(无需创建 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

标签: pythonlinuxdockerpipuvloop

解决方案


进一步谷歌搜索后,发现这里的问题是较新版本的 Alpine Linux (3.14+)需要 Docker 20.10.0 或更高版本

将 Alpine 降级到 3.13 可以正确构建。

鉴于构建系统上的 Ubuntu 16.04 自 2021 年 4 月起停产,我的目标是升级它,而不是为构建固定旧版本的 Alpine。


推荐阅读