我有一个用于准备Docker映像的脚本。我在Dockerfile中有这个文件:
COPY my_script /
RUN bash -c "/my_script"
my_script
文件包含图像中不需要的秘密(完成后会自动删除)。
问题在于,由于COPY是一个单独的图层,因此尽管删除了该文件仍保留在图像中。我需要的是COPY和RUN都影响同一层。
如何复制和运行脚本,以便两个动作都影响同一层?
答案 0 :(得分:1)
看看multi-stage:
使用多阶段构建
对于多阶段构建,您可以在自己的数据库中使用多个FROM语句 Dockerfile。每个FROM指令可以使用不同的基数,并且每个 他们中的一个开始了构建的新阶段。您可以有选择地复制 从一个阶段到另一个阶段的人工制品, 不需要最后一张图片。为了说明它是如何工作的,我们来调整一下 上一节中的Dockerfile使用多阶段构建。
Dockerfile:
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
答案 1 :(得分:1)
从18.09开始,您可以在构建过程中使用docker build --secret
使用秘密信息。这些秘密将被安装到构建环境中,并且不会存储在最终映像中。
conda install plotly
RUN --mount=type=secret,id=script,dst=/my_script \
bash -c /my_script
该脚本不需要删除自身。
答案 2 :(得分:0)
我想您可以使用一种解决方法来做到这一点:
将my_script
放置在本地http服务器中,例如使用python -m SimpleHTTPServer
,然后可以使用http://http_server_ip:8000/my_script
来访问文件
然后,在Dockerfile中使用下一步:
RUN curl http://http_server_ip:8000/my_script > /my_script && chmod +x /my_script && bash -c "/my_script"
此解决方法确保文件在同一层中添加和删除,当然,您可能需要在curl
中添加Dockerfile
安装。
答案 3 :(得分:0)
这可以通过BuildKit处理:
# syntax=docker/dockerfile:experimental
FROM ...
RUN --mount=type=bind,target=/my_script,source=my_script,rw \
bash -c "/my_script"
然后您将使用:
DOCKER_BUILDKIT=1 docker build -t my_image .
这听起来也像是您尝试将机密信息注入到构建文件中,例如从私人git仓库中提取。 BuildKit还允许您指定:
# syntax=docker/dockerfile:experimental
FROM ...
RUN --mount=type=secret,target=/creds,id=cred \
bash -c "/my_script -i /creds"
然后您将使用:
DOCKER_BUILDKIT=1 docker build -t my_image --secret id=creds,src=./creds .
使用这两个BuildKit选项,mount命令都不会实际将文件添加到映像中。它仅使文件在该单个RUN步骤中可用作绑定安装。只要该RUN步骤不会将机密输出到映像中的另一个文件,该机密就永远不会注入到映像中。
有关BuildKit实验语法的更多信息,请参见:https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md
答案 4 :(得分:0)
我认为BuildKit中的RUN --mount=type=bind,source=my_script,target=/my_script bash /my_script
可以解决您的问题。
首先,准备BuildKit
export DOCKER_CLI_EXPERIMENTAL=enabled
export DOCKER_BUILDKIT=1
docker buildx create --name mybuilder --driver docker-container
docker buildx use mybuilder
然后,编写您的Dockerfile。
# syntax = docker/dockerfile:experimental
FORM debian
## something
RUN --mount=type=bind,source=my_script,target=/my_script bash -c /my_script
第一个皮棉必须为#语法= docker / dockerfile:experimental ,因为它是实验性功能。
此方法不适用于docker的Play,但可以在我的计算机上使用...
我的计算机使用带有docker 19.03.12的Ubuntu 20.04
然后,用
构建它docker buildx build --platform linux/amd64 -t user/imgname -f ./Dockerfile . --push