Dockerfile无法复制文件("cp"命令)

6
我的Dockerfile包含一些cp Linux命令。因为项目中的某些文件被声明为示例,例如xxx.php.sample,应该替换为xxx.php
我认为这个过程应该在Dockerfile上执行。所以我写成了这样。
Dockerfile-php-apache
FROM php:5.5-apache
RUN apt-get update && \
  docker-php-ext-install pdo_mysql mysqli mbstring
RUN a2enmod rewrite
RUN a2enmod substitute
ADD . /var/www
WORKDIR /var/www
RUN cp config.php.sample config.php
RUN cp shared_config.php.sample shared_config.php
RUN cp vendor/propel/propel1/build.properties.sample vendor/propel/propel1/build.properties
RUN sed -i -E "s/host=(.*);/host=mysql-db;/" ./vendor/propel/propel1/build.properties
COPY docker-php-apache/php.ini /usr/local/etc/php/

docker-compose.yml

version: '2'
services:
  mysql-db:
    build:
      context: .
      dockerfile: Dockerfile-mysql-server
    ports:
      - "3306:3306"
  php-apache:
    build:
      context: .
      dockerfile: Dockerfile-php-apache
    volumes:
      - .:/var/www
    ports:
      - "80:80"
    depends_on:
      - mysql-db

在执行docker-compose builddocker-compose up(没有出现错误)后,这里是cp结果。

RUN cp config.php.sample config.php -> 未找到config.php
RUN cp shared_config.php.sample shared_config.php -> 未找到shared_config.php
RUN cp vendor/propel/propel1/build.properties.sample vendor/propel/propel1/build.properties -> 未找到build.properties

我认为路径可能有问题,所以我复制了上面的命令并直接执行它(我可以通过docker exec -it xxx_php-apache_1 bash登录容器)。
cp命令成功运行,我可以在容器和本地源中找到复制的文件。
有人知道为什么在Dockerfile中使用cp命令无法正常工作吗?
这是相应的构建日志。
Step 5 : COPY config.php.sample /var/www/config.php
 ---> afa7e6139049
Removing intermediate container 38b9968ac061
Step 6 : COPY shared_config.php.sample /var/www/shared_config.php
 ---> 78ea51045d4e
Removing intermediate container fe0b382914bd
Step 7 : COPY vendor/propel/propel1/build.properties.sample /var/www/vendor/propel/propel1/build.properties
 ---> 34c186a193c0
Removing intermediate container c55bb9565035
Step 8 : COPY docker-php-apache/php.ini /usr/local/etc/php/
 ---> 4e3e92aa0f97
Removing intermediate container f2c424eb6c38
Successfully built 4e3e92aa0f97

以防万一,我在容器上执行了find命令。

root@d98556ed051a:/var/www# find / -iname '*shared_config.php*' 
/var/www/shared_config.php.sample

另外,我已经用另一台笔记本电脑进行了测试,但结果是相同的。 以下是测试过的电脑:

  • Mac mini (Mid 2011) OS X Yosemite
  • Mac book pro (Late 2011) OS X Sierra

每台电脑都在使用 Docker for Mac,版本号为 1.12.1 (build: 12133)。

2个回答

4

方法1
我认为下面的Dockerfile语句可以更改
原来:

ADD . /var/www
WORKDIR /var/www
RUN cp config.php.sample config.php
RUN cp shared_config.php.sample shared_config.php
RUN cp vendor/propel/propel1/build.properties.sample vendor/propel/propel1/build.properties

收件人:

ADD config.php.sample /var/www/config.php
ADD shared_config.php.sample /var/www/shared_config.php
ADD vendor/propel/propel1/build.properties.sample /var/www/vendor/propel/propel1/build.properties 

当然,在上面的例子中你也可以使用COPY代替ADD

方法二
将下面的语句改为:

RUN cp config.php.sample config.php
RUN cp shared_config.php.sample shared_config.php
RUN cp vendor/propel/propel1/build.properties.sample vendor/propel/propel1/build.properties

致:

RUN ["cp",  "config.php.sample", "config.php"]
RUN ["cp", "shared_config.php.sample", "shared_config.php"]
RUN ["cp", "vendor/propel/propel1/build.properties.sample", "vendor/propel/propel1/build.properties"]

更多细节请参考文档。希望这对您有所帮助。

谢谢您向我展示了两种方法。我测试了这两种方法,但都没有成功。在第一种方法中,我可以看到所有的源代码都被复制到了容器中,并且 WORKDIR(我登录时的初始位置)被更改为 /var/www/html(嗯...应该是 /var/www,因为 docker-compose.yml 中描述的是这样的吧?)。在第二种方法中,我意识到您在第三行拼写了 ' 和 ",所以进行了更正并进行了测试。 - dosuken123
@dosuken123,感谢您的反馈。这很令人惊讶和奇怪。您最近注意到的错误是什么?您确定镜像中存在/var/www吗?或者您想尝试创建它? - Rao
pwd -> /var/www/html。嗯,我正在使用Docker For Mac。显然我应该重新安装它...?'/var/www/html'是php-apache的常见文件夹。因此,既然我正在使用官方的docker镜像,它应该在那里。 - dosuken123
没听懂你的意思。是方法1还是方法2出现了后续错误?此外,您是否需要将文件放在/var/www/html而不是/var/www中呈现?请澄清一下。 - Rao
无论哪种方式,都没有出现错误,例如docker-compose构建失败。只是缺少了预期的文件。我的项目顶层包含一个“html”文件夹。因此,如果我将所有源代码挂载到“/var/www”,一切看起来都很好。 - dosuken123

0

由于某种原因,似乎通过Dockerfile的RUN指令运行的cp命令不希望第二个参数是目标文件名。

请考虑以下内容:

RUN cp config.php.sample config.php

未找到config.php

它不应该尝试查找config.php,而是应该创建它。


我认为你最好使用以下命令:

RUN mv config.php.sample config.php

这将删除您现在无用的config.php.sample文件。实际上,它不会删除或创建任何内容,只是重命名您的文件--这正是您想要的:)


实际上,在使用cp之前,我一直在使用mv。但是在重新进行docker-compose构建和启动时,mv存在一个问题(尽管它仍然可以工作)。因为原始文件已被重命名并消失了。 - dosuken123
1
这至少可以说是很奇怪。所以 docker-compose build 修改了一个已经存在的镜像而不是创建一个新的?或者 ADD 指令会以某种方式使得所有对目标文件夹的更改都反映在它们原始位置上,也就是在你的本地机器上,在镜像之外?这听起来非常不对劲... 你能再试一次吗,确保你没有漏掉任何东西? - ccjmne
我的Docker镜像有时会出现问题,因此在构建之前我总是删除镜像和容器。删除命令是“docker rmi -f XXX”,我确保之前的镜像已经被删除。对于容器,我使用docker rm -f $(docker ps -a -q) - dosuken123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接