如何使用Docker文件中的"ADD"命令包含Docker构建上下文之外的文件?
从Docker文档:
路径必须位于构建的上下文中; 你不能添加../something/something,因为docker构建的第一步是将上下文目录(和子目录)发送到docker守护进程.
我不想重构我的整个项目只是为了适应Docker这个问题.我想将所有Docker文件保存在同一个子目录中.
此外,似乎Docker还没有(也可能不会)支持符号链接:Dockerfile ADD命令不遵循主机#1676上的符号链接.
我能想到的唯一另一件事是包含一个预构建步骤,将文件复制到Docker构建上下文中(并配置我的版本控制以忽略这些文件).还有比这更好的解决方法吗?
Cyb*_*wiz 340
解决此问题的最佳方法是使用-f独立于构建上下文指定Dockerfile.
例如,此命令将使ADD命令可以访问当前目录中的任何内容.
docker build -f docker-files/Dockerfile .
Run Code Online (Sandbox Code Playgroud)
更新:Docker现在允许在构建上下文之外使用Dockerfile(修复于18.03.0-ce,https://github.com/docker/cli/pull/886).所以你也可以这样做
docker build -f ../Dockerfile .
Run Code Online (Sandbox Code Playgroud)
Gün*_*uer 43
在Linux上,您可以挂载其他目录而不是对它们进行符号链接
mount --bind olddir newdir
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅https://superuser.com/questions/842642.
我不知道其他操作系统是否有类似的东西可用.我还尝试使用Samba共享一个文件夹并将其重新安装到Docker上下文中,该上下文也可以使用.
use*_*308 41
我经常发现自己--build-arg为此目的使用了这个选项.例如,在Dockerfile中放入以下内容之后:
ARG SSH_KEY
RUN echo "$SSH_KEY" > /root/.ssh/id_rsa
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
docker build -t some-app --build-arg SSH_KEY="$(cat ~/file/outside/build/context/id_rsa)" .
Run Code Online (Sandbox Code Playgroud)
但请注意Docker文档中的以下警告:
警告:建议不要使用构建时变量来传递github密钥,用户凭据等秘密.使用docker history命令可以使映像的任何用户都可以看到构建时变量值.
Mar*_*les 19
我花了很多时间试图找出一个好的模式,以及如何更好地解释这个功能支持正在发生什么.我意识到解释它的最好方法如下......
所以,说到这里,这是一个需要重用被调用文件的Dockerfile的例子 start.sh
它将ALWAYS从其相对路径加载,将其自身的当前目录作为对local指定路径的引用.
COPY start.sh /runtime/start.sh
Run Code Online (Sandbox Code Playgroud)
考虑到这个想法,我们可以考虑为Dockerfiles构建特定内容的多个副本,但它们都需要访问start.sh.
./all-services/
/start.sh
/service-X/Dockerfile
/service-Y/Dockerfile
/service-Z/Dockerfile
./docker-compose.yaml
Run Code Online (Sandbox Code Playgroud)
考虑到这个结构和上面的文件,这里是一个docker-compose.yml
shared上下文目录是runtimedir.
context.dockerfile.的docker-compose.yml是如下
version: "3.3"
services:
service-A
build:
context: ./all-service
dockerfile: ./service-A/Dockerfile
service-B
build:
context: ./all-service
dockerfile: ./service-B/Dockerfile
service-C
build:
context: ./all-service
dockerfile: ./service-C/Dockerfile
Run Code Online (Sandbox Code Playgroud)
all-service设置为上下文,共享文件start.sh以及每个文件指定的Dockerfile dockerfile.干杯!
Usm*_*ail 18
如果您阅读问题2745中的讨论,不仅docker可能永远不会支持符号链接,他们可能永远不会支持在您的上下文之外添加文件.似乎是一种设计理念,即进入docker构建的文件应明确地成为其上下文的一部分,或者来自URL,其中也可能使用固定版本进行部署,以便使用随附的众所周知的URL或文件重复构建.码头工人集装箱.
我更喜欢使用版本控制源构建 - 即docker build -t stuff http://my.git.org/repo - 否则我将使用随机文件从一些随机位置构建.
从根本上说,没有.... - SvenDowideit,Docker Inc
只是我的意见,但我认为你应该重组以分离代码和docker存储库.这样,容器可以是通用的,并在运行时提取任何版本的代码而不是构建时间.
或者,使用docker作为基本代码部署工件,然后将dockerfile放在代码存储库的根目录中.如果你去这条路线可能有意义的是有一个父Docker容器用于更一般的系统级细节和一个子容器用于特定于你的代码的设置.
isc*_*sca 15
docker此行为由或podman用于将文件呈现给构建过程的上下文目录给出。
这里的一个不错的技巧是在构建指令期间将上下文目录更改为要向守护程序公开的目录的完整路径。例如:
docker build -t imageName:tag -f /path/to/the/Dockerfile /mysrc/path
Run Code Online (Sandbox Code Playgroud)
使用/mysrc/path而不是.(当前目录),您将使用该目录作为上下文,因此构建过程可以看到该目录下的任何文件。
在这个示例中,您将把整个/mysrc/path树暴露给 docker 守护进程。
当将此与docker触发构建的用户 ID 一起使用时,必须对上下文目录中的任何单个目录或文件具有递归读取权限。
如果您拥有/home/user/myCoolProject/Dockerfile 但想要将不在同一目录中的文件引入此容器构建上下文,这可能会很有用。
这是使用 context dir 构建的示例,但这次使用podman而不是docker.
Dockerfile让我们举个例子,在你的aCOPY或指令中ADD,它从项目外部的目录复制文件,例如:
FROM myImage:tag
...
...
COPY /opt/externalFile ./
ADD /home/user/AnotherProject/anotherExternalFile ./
...
Run Code Online (Sandbox Code Playgroud)
为了构建这个,使用位于 中的容器文件/home/user/myCoolProject/Dockerfile,只需执行以下操作:
cd /home/user/myCoolProject
podman build -t imageName:tag -f Dockefile /
Run Code Online (Sandbox Code Playgroud)
一些已知的更改上下文目录的用例是使用容器作为构建源代码的工具链。
例如:
FROM myImage:tag
...
...
COPY /opt/externalFile ./
ADD /home/user/AnotherProject/anotherExternalFile ./
...
Run Code Online (Sandbox Code Playgroud)
或者它可以是相对路径,例如:
cd /home/user/myCoolProject
podman build -t imageName:tag -f Dockefile /
Run Code Online (Sandbox Code Playgroud)
这次使用全局路径的另一个示例:
FROM myImage:tag
...
...
COPY externalFile ./
ADD AnotherProject ./
...
Run Code Online (Sandbox Code Playgroud)
请注意,现在Dockerfile 命令层中省略了COPY和的完整全局路径。ADD
在这种情况下,contex dir必须相对于文件所在的位置,如果 和externalFile都AnotherProject在/opt目录中,则context dir构建它的位置必须是:
podman build -t imageName:tag -f ./Dockerfile /opt
Run Code Online (Sandbox Code Playgroud)
使用COPY或ADD与 context dir indocker时请注意:
守护docker进程将尝试将上下文目录树上可见的所有文件“流”到守护进程,这可能会减慢构建速度。并要求用户具有上下文目录的递归权限。这种行为的成本可能会更高,特别是在通过 API 使用构建时。然而,podman构建是即时发生的,不需要递归权限,这是因为它podman没有枚举整个上下文目录,也没有使用client/server架构。当您使用不同的上下文目录遇到此类问题时,针对此类情况
的构建可能会更有趣,而不是使用。podmandocker
一些参考:
小智 13
我认为今年早些时候,buildx 中添加了一个功能来做到这一点。
\n如果您有 dockerfile 1.4+ 和 buildx 0.8+,您可以执行以下操作:
\ndocker buildx build --build-context othersource= ../something/something .\nRun Code Online (Sandbox Code Playgroud)\n然后在你的 docker 文件中你可以使用 from 命令添加上下文
\nADD \xe2\x80\x93-from=othersource . /stuff\nRun Code Online (Sandbox Code Playgroud)\n请参阅此相关帖子。
\n您还可以创建图像首先需要的 tarball 并将其用作您的上下文。
https://docs.docker.com/engine/reference/commandline/build/#/tarball-contexts
我认为更简单的解决方法是更改“上下文”本身。
因此,例如,与其给出:
docker build -t hello-demo-app .
Run Code Online (Sandbox Code Playgroud)
它将当前目录设置为上下文,假设您希望将父目录作为上下文,只需使用:
docker build -t hello-demo-app ..
Run Code Online (Sandbox Code Playgroud)
小智 5
使用 docker-compose,我通过创建一个服务来挂载我需要的卷并提交容器的映像来实现这一点。然后,在后续服务中,我依赖先前提交的映像,该映像将所有数据存储在安装位置。然后,您必须将这些文件复制到它们的最终目的地,因为在运行docker commit命令时不会提交主机安装的目录
您不必使用 docker-compose 来完成此操作,但它使生活更轻松
# docker-compose.yml
version: '3'
services:
stage:
image: alpine
volumes:
- /host/machine/path:/tmp/container/path
command: bash -c "cp -r /tmp/container/path /final/container/path"
setup:
image: stage
Run Code Online (Sandbox Code Playgroud)
# setup.sh
# Start "stage" service
docker-compose up stage
# Commit changes to an image named "stage"
docker commit $(docker-compose ps -q stage) stage
# Start setup service off of stage image
docker-compose up setup
Run Code Online (Sandbox Code Playgroud)
docker build然后删除文件。我的快速浏览中没有提到一个简单的解决方案:
docker_build.shdocker buildsudo bind另一个安全漏洞,因为它需要 root 权限才能执行bind。| 归档时间: |
|
| 查看次数: |
170822 次 |
| 最近记录: |