代码之家  ›  专栏  ›  技术社区  ›  starfry

Dockerfile复制并在一个层中运行

  •  0
  • starfry  · 技术社区  · 7 年前

    我有一个脚本用于Docker图像的预制作。我在Dockerfile中有这样一个文件:

    COPY my_script /
    RUN bash -c "/my_script"
    

    这个 my_script 文件中包含我不希望出现在图像中的秘密(完成后会自动删除)。

    问题是,尽管被删除,文件仍保留在图像中,因为副本是一个单独的层。我需要的是复制和运行都影响同一层。

    如何复制和运行脚本,使两个操作都影响同一层?

    1 回复  |  直到 7 年前
        1
  •  8
  •   LinPy    7 年前

    看看 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"]  
    
        2
  •  7
  •   John Kugelman Michael Hodel    7 年前

    从18.09起,您可以使用 docker build --secret 在构建过程中使用机密信息。这些秘密被装载到构建环境中,不会存储在最终映像中。

    RUN --mount=type=secret,id=script,dst=/my_script \
        bash -c /my_script
    
    $ docker build --secret id=script,src=my_script.sh
    

    脚本不需要删除自己。

        3
  •  5
  •   BMitch    7 年前

    这可以由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命令实际上从未将文件添加到映像中。在单次运行步骤中,它仅使文件作为绑定装载可用。只要运行步骤没有将机密输出到图像中的另一个文件,该机密就永远不会被注入图像中。

    有关BuildKit实验语法的更多信息,请参阅: https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md

        4
  •  2
  •   atline    7 年前

    我想你可以使用一种变通方法来做到这一点:

    my_script 在本地http服务器中,例如使用 python -m SimpleHTTPServer ,然后可以使用 http://http_server_ip:8000/my_script

    然后,在Dockerfile中使用next:

    RUN curl http://http_server_ip:8000/my_script > /my_script && chmod +x /my_script && bash -c "/my_script"
    

    此解决方案确保文件添加&删除同一层,当然,你可能需要添加 curl 安装在 Dockerfile .

        5
  •  0
  •   JK-Hu    6 年前

    我想 RUN --mount=type=bind,source=my_script,target=/my_script bash /my_script 在BuildKit中可以解决您的问题。

    首先,准备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 
    

    第一根绒线必须是 #syntax=docker/dockerfile:实验性 因为这是实验性的特征。

    这个方法不是docker的工作,而是在我的电脑上工作。。。

    我的电脑使用Ubuntu20.04和docker 19.03.12

    然后,用

    docker buildx build --platform linux/amd64 -t user/imgname -f ./Dockerfile . --push
    
    推荐文章