Dockerfile COPY指令失败?

j1dl9f46  于 2023-04-29  发布在  Docker
关注(0)|答案(7)|浏览(428)

所有的,我试图持久地复制文件从我的主机到一个图像,使这些文件可与每个容器启动的基础上,该图像。在debian wheezy 64bit上作为virtualbox guest运行。
Dockerfile非常简单(安装octave镜像):

FROM debian:jessie 
MAINTAINER GG_Python <[redacted]@gmail.com>
RUN apt-get update 
RUN apt-get update
RUN apt-get install -y octave octave-image octave-missing-functions octave-nan octave-statistics

RUN mkdir /octave
RUN mkdir /octave/libs
RUN mkdir /octave/libs/jsonlab
COPY ~/octave/jsonlab/loadjson.m /octave/libs/jsonlab/.

在发出build命令后,我得到以下跟踪:docker build -t octave .

Sending build context to Docker daemon 423.9 kB
Sending build context to Docker daemon 
Step 0 : FROM debian:jessie
 ---> 58052b122b60
Step 1 : MAINTAINER GG_Python <[..]@gmail.com>
 ---> Using cache
 ---> 90d2dd2f7ee8
Step 2 : RUN apt-get update
 ---> Using cache
 ---> 4c72c25cd829
Step 3 : RUN apt-get update
 ---> Using cache
 ---> b52f0bcb9f86
Step 4 : RUN apt-get install -y octave octave-image octave-missing-functions octave-nan octave-statistics
 ---> Using cache
 ---> f0637ab96d5e
Step 5 : RUN mkdir /octave
 ---> Using cache
 ---> a2d278b2819b
Step 6 : RUN mkdir /octave/libs
 ---> Using cache
 ---> 65efbbe01c99
Step 7 : RUN mkdir /octave/libs/jsonlab
 ---> Using cache
 ---> e41b80901266
Step 8 : COPY ~/octave/jsonlab/loadjson.m /octave/libs/jsonlab/.
INFO[0000] ~/octave/jsonlab/loadjson.m: no such file or directory

Docker绝对拒绝将此文件从主机复制到镜像中。不用说文件loadjson。m在那里(cat显示),我所有试图改变路径的尝试(相对的,绝对的,等等。)失败。有什么建议为什么这个简单的任务是有问题的吗?

ax6ht2ek

ax6ht2ek1#

在我最初写这篇文章的时候,Docker并没有扩展~或$HOME。现在它在构建上下文中进行了一些扩展,但即使这样,它们也可能不是您想要的-它们不是上下文之外的主目录。您需要显式引用该文件,或者将其相对于Dockerfile本身打包。

raogr8fs

raogr8fs2#

Docker只能从上下文中复制文件,即您所在的文件夹减去dockerignore文件中列出的任何文件。
当你运行'docker build'时,docker会将上下文定位并发送到你所连接的docker守护进程。它只允许您复制上下文内的文件,因为守护进程可能是远程机器。

kq0g1dla

kq0g1dla3#

我无法让COPY工作,直到我理解上下文(我试图从上下文之外复制一个文件)
docker build命令从Dockerfile和context构建镜像。构建的上下文是指定位置PATH的文件。PATH是本地文件系统上的一个目录。
上下文被递归地处理。因此,PATH包含所有子目录。
构建由Docker守护进程运行,而不是CLI。构建进程所做的第一件事是将整个上下文(递归地)发送给守护进程。在大多数情况下,最好从一个空目录开始作为上下文,并将Dockerfile保存在该目录中。仅添加构建Dockerfile所需的文件。
警告:不要使用根目录/作为PATH,因为它会导致构建将硬盘驱动器的全部内容传输到Docker守护进程。
参考: www.example.com

50few1ms

50few1ms4#

我有类似的问题。我通过检查两件事来解决它:
1.在你的docker-compose.yaml检查context服务中,docker不会复制这个目录之外的任何文件。例如,如果contextapp/,则无法从../app复制任何内容
1.检查.dockerignore以确保您没有忽略要复制的文件。

tnkciper

tnkciper5#

我首先检查上下文是什么,在Dockerfile中的源文件之前设置一个绝对路径来获取该信息:

# grep COPY Dockerfile
COPY /path/to/foo   /whatever/path/in/destination/foo

用它来建造:

docker build -t bar/foo .

你会得到一个错误,它指出了Docker显然正在寻找它的文件的上下文路径,e。g.结果是:

/var/lib/docker/tmp      # I don't remember

复制(!)您的构建文件集到该目录(这里:/var/lib/docker/tmp),cd到它,从那里构建。
看看这是否有效,不要忘记做一些内务清理tmp,删除您的文件之前下次访问(或)。
高温加热
迈克尔

bnl4lu3b

bnl4lu3b6#

在Windows机器上使用Linux容器的Dockerfile时出现此错误:

24 1.160跳过项目“/src/Common/MetaData/Metadata.csproj”,因为找不到。

还原在主机上工作正常。
原来是这里提到的错误:
https://stackoverflow.com/a/68592423/3850405
.csproj文件与Visual Studio与文件系统中的大小写不匹配。

p3rjfoxz

p3rjfoxz7#

除了正确的上下文之外,DockerfileCOPY和bash cp命令之间还存在语义差异。
bash中的示例:

~: mkdir -p a/b
~: mkdir c
~: touch a/file1 a/b/file2
~: cp -R a c  # Copying directory 'a' to 'c', recursively
~: ls -lR c # Listing directory 'c', recursively
c:
total 0
drwxr-xr-x 4 teixeira staff 128 Abr 20 11:08 a

c/a:
total 0
drwxr-xr-x 3 teixeira staff 96 Abr 20 11:08 b
-rw-r--r-- 1 teixeira staff  0 Abr 20 11:08 file1

c/a/b:
total 0
-rw-r--r-- 1 teixeira staff 0 Abr 20 11:08 file2

Dockerfile.teste

FROM debian:bullseye-slim

RUN mkdir c
WORKDIR c

# Here's the issue, you will see soon why
COPY ./a . # Copying directory 'a' to 'c', recursively

RUN ls -lR . # listing directory 'c', recursively

docker-compose.yml

version: '3.8'
services:
  teste:
    image: teste
    build:
      # My local context is correct, just for completeness  
      context: $RAIZ_PROJETO
      dockerfile: docker/Dockerfile.teste

. env

RAIZ_PROJETO=/home/vagrant/docker/testes

现在,构建上面的图像的输出:

~: sudo docker compose build --progress plain --no-cache teste

(...)
#6 [2/5] RUN mkdir c
#6 DONE 0.4s

#7 [3/5] WORKDIR c
#7 DONE 0.0s

#8 [4/5] COPY ./a .
#8 DONE 0.0s

#9 [5/5] RUN ls -lR .
#9 0.306 .:
#9 0.306 total 4
#9 0.306 drwxr-xr-x 2 root root 4096 Apr 20 14:33 b
#9 0.306 -rw-r--r-- 1 root root    0 Apr 20 14:13 file1
#9 0.306
#9 0.306 ./b:
#9 0.306 total 0
#9 0.306 -rw-r--r-- 1 root root 0 Apr 20 14:13 file2
#9 DONE 0.3s
(...)

你注意到区别了吗?目录a * content * 被复制到docker镜像中的目录c,而不是a本身!

    • TL; DR;**

当你在bash中复制一个目录到一个目的地时,目录 * 本身 * 被复制到目的地。这与COPY不同,在COPY中,如果你想复制目录本身,你必须在目标中指定它的名称 * again *。
所以,要修复上面的Dockerfile,只需重复目录源到COPY目标:

COPY ./a ./a

docker compose build的正确输出

#9 [5/5] RUN ls -lR .
#9 0.341 .:
#9 0.341 total 4
#9 0.341 drwxr-xr-x 3 root root 4096 Apr 20 14:48 a
#9 0.341
#9 0.341 ./a:
#9 0.341 total 4
#9 0.341 drwxr-xr-x 2 root root 4096 Apr 20 14:33 b
#9 0.341 -rw-r--r-- 1 root root    0 Apr 20 14:13 file1
#9 0.341
#9 0.341 ./a/b:
#9 0.341 total 0
#9 0.341 -rw-r--r-- 1 root root 0 Apr 20 14:13 file2
#9 DONE 0.4s

相关问题