在另一个镜像中使用构建器镜像中安装的 apk 包

using apk packages that were installed in a builder image in an other image

我有一个(多阶段)alpine 构建器映像,它安装了一些 apk 包 (postgres) 和一个 Go 应用程序。然后我有另一个从这个图像扩展的图像,需要使用安装在其中的 apk 包。然而,apk 包似乎不在最终图像中。我构建了构建器映像并 运行 它和 apk 包也没有安装在那里...

建造者:

FROM golang:1.18-alpine AS base
RUN apk add --no-cache --quiet musl-dev git gcc upx postgresql-client

RUN LDFLAGS="-s -w -linkmode external -extldflags \"-static\"" &&\
    go install --ldflags "$LDFLAGS" github.com/GoogleCloudPlatform/cloudsql-proxy/cmd/cloud_sql_proxy@latest &&\
    upx /go/bin/cloud_sql_proxy

# Build the dist image
FROM alpine
COPY --from=base /go/bin/cloud_sql_proxy /

最终图片:

# syntax=docker/dockerfile:experimental

# set default PSQLCONNECTOR_VERSION value
ARG PSQLCONNECTOR_VERSION=20220425

# pull from base image
FROM gcr.io/mycrepo/psql-cloudproxy-connector:$PSQLCONNECTOR_VERSION-alpine AS base

# copy script
COPY ./some_script.sh /

# make the script executable
RUN ["chmod", "+x", "/some_script.sh"]

some_script.sh 包含:

PG_URL="postgresql://postgres:password@localhost:5432/some_db?sslmode=disable"
psql "$PG_URL" -c "SELECT * FROM ...;"

psql(来自 postgresql-client pkg)在第二张图片中不存在。当脚本为 运行 时,我们得到 /some_script.sh: line 35: psql: not found.

这是最终容器中 apk list 的输出:

apk list
WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.15/main: No such file or directory
WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.15/community: No such file or directory
libretls-3.3.4-r3 x86_64 {libretls} (ISC AND (BSD-3-Clause OR MIT)) [installed]
musl-1.2.2-r7 x86_64 {musl} (MIT) [installed]
zlib-1.2.12-r0 x86_64 {zlib} (Zlib) [installed]
apk-tools-2.12.7-r3 x86_64 {apk-tools} (GPL-2.0-only) [installed]
musl-utils-1.2.2-r7 x86_64 {musl} (MIT BSD GPL2+) [installed]
libssl1.1-1.1.1n-r0 x86_64 {openssl} (OpenSSL) [installed]
alpine-baselayout-3.2.0-r18 x86_64 {alpine-baselayout} (GPL-2.0-only) [installed]
alpine-keys-2.4-r1 x86_64 {alpine-keys} (MIT) [installed]
busybox-1.34.1-r5 x86_64 {busybox} (GPL-2.0-only) [installed]
scanelf-1.3.3-r0 x86_64 {pax-utils} (GPL-2.0-only) [installed]
ca-certificates-bundle-20211220-r0 x86_64 {ca-certificates} (MPL-2.0 AND MIT) [installed]
libc-utils-0.7.2-r3 x86_64 {libc-dev} (BSD-2-Clause AND BSD-3-Clause) [installed]
ssl_client-1.34.1-r5 x86_64 {busybox} (GPL-2.0-only) [installed]
libcrypto1.1-1.1.1n-r0 x86_64 {openssl} (OpenSSL) [installed]

我的印象是构建一个从安装了 apk 包的图像 B 扩展的图像 A 会得到一个图像 A 和安装在图像 B 中的包。但似乎安装的包甚至没有在两者之间共享同一个 Dockerfile 中的多个阶段?

将这些包复制到最终镜像A的正确方法是什么?

ps。图像需要分开,因为我需要在不同的时间构建它们,所以单个多阶段构建没有用

Dockerfile 中的第二个 FROM 语句将映像完全重置为新的基础映像。什么都没有结转。从早期阶段获得某些东西的唯一方法是 COPY --from=... 语句。

如果您在最终映像中需要一些包,您应该在最终映像中安装它们。从早期阶段复制它们将很困难,因为您需要知道软件包安装了哪些文件。

在您的情况下,您应该在 alpine 映像中安装软件包。然后它们也将出现在您基于高山图像制作的最终图像中。