Docker:从父目录中添加文件

在我的Dockerfile中,我得到:

ADD ../../myapp.war /opt/tomcat7/webapps/

该文件存在,因为ls ../../myapp.war返回我正确的文件,但当我执行sudo docker build -t myapp .时,我得到:

Step 1 : ADD ../../myapp.war /opt/tomcat7/webapps/
2014/07/02 19:18:09 ../../myapp.war: no such file or directory

有人知道为什么和如何正确地做吗?

324133 次浏览

不幸的是(我猜是出于实际和安全原因),如果你想添加/复制本地内容,它必须位于与Dockerfile相同的根路径下。

的文档:

< p > & lt; src>路径必须在构建的上下文中;你 不能添加../某事/something,因为docker的第一步 构建是将上下文目录(和子目录)发送到 码头工人守护进程。< / p >

现在有一个选项(-f)来设置Dockerfile的路径;你可以用它来达到你想要的,看看@Boedy的回应。

  1. cd改为你的父目录
  2. 从父目录构建映像,指定Dockerfile的路径
docker build -t <some tag> -f <dir/dir/Dockerfile> .

在这种情况下,docker的上下文将切换到父目录,供ADD和COPY访问

对于那些使用composer的人来说,解决方案是使用体积指向父文件夹:

#docker-composer.yml


foo:
build: foo
volumes:
- ./:/src/:ro

但我很确定可以用卷在Dockerfile来完成。

由于-f引起了另一个问题,我开发了另一个解决方案。

  • 在父文件夹中创建一个基本映像
  • 添加所需文件。
  • 使用此图像作为子代文件夹中项目的基本图像。

-f标志并没有解决我的问题,因为我的onbuild映像在一个文件夹中寻找一个文件,并且必须像这样调用:

-f foo/bar/Dockerfile foo/bar

而不是

-f foo/bar/Dockerfile .

还要注意,这只是在某些情况下作为-f标志的解决方案

使用docker-compose,你可以设置上下文文件夹:

# docker-compose.yml


version: '3.3'
services:
yourservice:
build:
context: ./
dockerfile: ./docker/yourservice/Dockerfile

添加一些代码片段来支持接受的答案。

目录结构:

setup/
|__docker/DockerFile
|__target/scripts/<myscripts.sh>
src/
|__<my source files>

Docker文件入口:

RUN mkdir -p /home/vagrant/dockerws/chatServerInstaller/scripts/
RUN mkdir -p /home/vagrant/dockerws/chatServerInstaller/src/
WORKDIR /home/vagrant/dockerws/chatServerInstaller


#Copy all the required files from host's file system to the container file system.
COPY setup/target/scripts/install_x.sh scripts/
COPY setup/target/scripts/install_y.sh scripts/
COPY src/ src/

用于构建docker映像的命令

docker build -t test:latest -f setup/docker/Dockerfile .

如果你正在使用skaffold,使用'context:'为每个图像指定上下文位置dockerfile - context: ../../../

            apiVersion: skaffold/v2beta4
kind: Config
metadata:
name: frontend
build:
artifacts:
- image: nginx-angular-ui
context: ../../../
sync:
# A local build will update dist and sync it to the container
manual:
- src: './dist/apps'
dest: '/usr/share/nginx/html'
docker:
dockerfile: ./tools/pipelines/dockerfile/nginx.dev.dockerfile
- image: webapi/image
context: ../../../../api/
docker:
dockerfile: ./dockerfile
deploy:
kubectl:
manifests:
- ./.k8s/*.yml

运行-f ./ Skaffold .yaml

  • 构建来自上目录的img

  • 命名img

  • 启用适当的卷共享

  • 检查Makefile在上面的链接如何启动容器…

    docker build . -t proj-devops-img --no-cache --build-arg UID=$(shell id -u) --build-arg GID=$(shell id -g) -f src/docker/devops/Dockerfile
    

假设你有这样的目录树:

dir0
├───dir1
│   └───dir11
|   |   └───dockerfile
|   └───dir12 (current)
└───dir2 (content to be copied)

你的dockerfile是这样的:

FROM baseImage
COPY / /content

假设你想要使用COPYdockerfile中的ADDdir2内容复制到一个新的docker映像中,而你的当前目录dir12

你必须运行这个命令,以正确地构建你的映像:

docker build -t image-name:tag -f ../dir11/dockerfile ../../dir2
  • -t your-image-name名称和可选的' Name:tag'格式的标记
  • -f ../dir11/dockerfile Dockerfile的名称(默认为'PATH/Dockerfile')
  • ../../dir2路径为COPY或ADD命令的当前路径

更新

假设你错误地运行了这个:

docker build -t image-name:tag -f ../dir11/dockerfile ../../

这并不能解决你的问题,因为在这种情况下,COPY / /content看起来像是在复制dir0的内容(dir1 &所以为了解决这个问题,你可以使用正确的路径改变命令,或者你也可以像这样改变dockerfile中的COPY源路径:

COPY /dir2 /content

Let setting context: ../..在docker-compose.yml的父文件夹中
. / 例:< br > < / p >

app:
build:
context: ../../
dockerfile: ./source/docker/dockerfile/Dockerfile

给定以下设置:

+ parent
+ service1
- some_file.json
+ service2
- Dockerfile

如果你在service2中有一个Dockerfile,并且想要从service1中复制some_file.json,你可以运行这个内部 service2目录:

docker build -t my_image ../ --file Dockerfile

这将把目标上下文设置在更高的级别上。这里棘手的部分是,目标Dockerfile是显式设置的(因为它不在目标上下文中)。

service2/Dockerfile中,你必须发出COPY命令,就好像文件在上面一层一样:

COPY service1/some_file.json /target/location/some_file.json

而不是

COPY ../service1/some_file.json /target/location/some_file.json # will not work