关于docker:Dockerfile中的路径解释

Path interpretation in a Dockerfile

我想运行一个容器,通过动态安装我的~/.ssh路径(以便能够克隆一些私有的gitlab存储库)。

这个

1
COPY ~/.ssh/ /root/.ssh/

指令不起作用,因为Dockerfile解释了它为构建创建的tmp dir的相关路径,例如。

1
/var/lib/docker/tmp/docker-builder435303036/

因此,我的下一个尝试是利用ARGS指令,如下所示:

1
2
3
ARG CURRENTUSER

COPY /home/$CURRENTUSER/.ssh/ /root/.ssh/

并以以下方式运行生成:

1
docker build --build-arg CURRENTUSER=pkaramol <whatever follows ...>

然而,我仍然面临着同样的问题:

1
COPY failed: stat /var/lib/docker/tmp/docker-builder435303036/home/pkaramol/.ssh: no such file or directory

1:如何使Dockerfile访问主机内的特定路径?

2:有没有比复制我的.sshdir更好的模式从短暂运行的容器中访问私有git repos?(我只是在构建过程中需要它)


Docker构建上下文

dockerfile的生成无法访问"build context"目录之外的特定路径。这是docker build的最后一个论点,通常是.docker build命令加速构建上下文,并将其发送到docker守护进程以从中构建映像。在生成中只能引用生成上下文中的文件。要包含用户.ssh目录,您需要在.ssh目录中建立内部版本,或者像/home/$USER这样的父目录。

建立秘密

COPYing或ADDing凭证在构建时输入是一个坏主意,因为凭证将保存在映像构建中,供任何有权访问映像的人查看。这里有几个注意事项。如果在build中删除敏感文件后展平图像层,或者创建一个多阶段build(17.05+),它只将不敏感的人工制品复制到最终图像中。

使用ENVARG也是不好的,因为秘密最终会出现在图像历史中。

有一个长期的涉及到Github的秘密问题,涵盖了大部分的思想变化。它很长,但值得一读里面的评论。

两种主要的解决方案是通过网络或卷获取机密。

在标准版本中,卷不可用,因此很难操作。

Docker增加了秘密功能,但这只在基于Swarm的容器运行时可用。

网络秘密习俗

Github的秘密问题有一个简单的网络猫例子。

1
nc -lp 10.8.8.8 8080 < $HOME/.ssh/id_rsa &

使用curl在dockerfile中收集,使用,在一个RUN步骤中取出。

1
2
3
4
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服务器就足够了。

1
2
3
4
docker run -d \
  -p 10.8.8.8:80:80 \
  -v /home/me/.ssh:/usr/share/nginx/html:ro \
  nginx

根据您的设置和安全要求,您可能需要添加TLS或身份验证。

哈希库普拱顶

保险库是专门为管理秘密而构建的工具。它超出了Docker构建的需求,它被编写并作为容器分发。

建造卷摇杆

Rocker是一个自定义Docker图像生成器,它扩展了DockerFiles以支持一些新功能。他们添加的MOUNT命令允许您在构建时装载卷。

封隔器

打包机Docker Builder还允许您在构建时装载任意卷。