我想运行一个容器,通过动态安装我的~/.ssh
路径(以便能够克隆一些私有gitlab存储库)。
COPY ~/.ssh/ /root/.ssh/
指令没有成功,因为Dockerfile
解释了相对于它为构建创建的tmp目录的路径,例如
/var/lib/docker/tmp/docker-builder435303036/
所以我的下一步是尝试利用ARGS
指令,如下所示:
ARG CURRENTUSER
COPY /home/$CURRENTUSER/.ssh/ /root/.ssh/
并将构建运行为:
docker build --build-arg CURRENTUSER=pkaramol <whatever follows ...>
但是,我仍然面临同样的问题:
COPY failed: stat /var/lib/docker/tmp/docker-builder435303036/home/pkaramol/.ssh: no such file or directory
1 :如何让Dockerfile
访问主机内的特定路径?
2 :从复制我的.ssh
目录开始,是否有更好的模式可以从短暂的正在运行的容器中访问私有git回购? (我只需要它来构建过程)
答案 0 :(得分:3)
Dockerfile的构建无法访问“构建上下文”目录之外的特定路径。这是docker build
的最后一个参数,通常为.
。 docker build
命令将构建上下文分解并将其发送到Docker守护程序以构建映像。只能在构建中引用构建上下文中的文件。要包含用户.ssh
目录,您需要将构建基于.ssh
目录或父目录(如/home/$USER
)。
COPY
或ADD
凭据是坏主意,因为凭据将保存在图像构建中,供有权访问该图像的任何人使用查看。这里有几点需要注意。如果在构建中删除敏感文件后展平图像图层,或创建仅将非敏感图像复制到最终图像中的multi stage build(17.05+)。
使用ENV
或ARG
也不错,因为秘密会在图片历史记录中结束。
有很长一段时间涉及github issue about secrets,涵盖了该想法的大多数变体。这很长,但值得通读那里的评论。
两个主要解决方案是通过网络或卷获取秘密。
标准版本中没有卷,因此这会使它们变得棘手。
Docker已添加secrets functionality但这仅适用于基于群集的容器的容器运行时。
秘密github问题有一个整洁的小net cat example。
nc -lp 10.8.8.8 8080 < $HOME/.ssh/id_rsa &
使用curl
在Dockerfile中收集它,使用它,并在RUN
步骤中删除它。
RUN set -uex; \
curl -s http://10.8.8.8:8000 > /root/.ssh/id_rsa; \
ssh -i /root/.ssh/id_rsa root@wherever priv-command; \
rm /root/.ssh/id_rsa;
要使不安全的网络服务可访问,您可能需要为您的环回接口添加别名IP地址,以便您的构建容器或本地服务可以访问它,但没有一个外部可以访问它。
只需在安装了密钥的情况下运行Web服务器就足够了。
docker run -d \
-p 10.8.8.8:80:80 \
-v /home/me/.ssh:/usr/share/nginx/html:ro \
nginx
您可能需要添加TLS或身份验证,具体取决于您的设置和安全要求。
Vault是专为管理机密而构建的工具。它超出了Docker构建的要求它的编写和Go以及distributed as a container。
Rocker是一个自定义Docker镜像构建器,它扩展了Dockerfiles以支持一些新功能。他们添加的MOUNT
命令允许您在构建时安装卷。
Packer Docker Builder还允许您在构建时安装任意卷。