Docker compose volume 在多阶段构建中覆盖 COPY

pet*_*ter 5 php docker docker-compose

我的目标是在 docker 文件的一个阶段获取 php 依赖项,然后将这些依赖项复制到下一阶段(vendor/目录)。但是,一旦在docker-compose.yml其中指定了一个卷,它就会覆盖该COPY语句,就好像它从未发生过一样。

docker-compose.yml

version: "3"

services:
  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    volumes:
      - .:/var/www/html
Run Code Online (Sandbox Code Playgroud)

docker/app/Dockerfile

FROM composer AS php_builder
COPY . /app
RUN composer install --no-dev

FROM php:7.1-fpm
COPY --from=php_builder /app/vendor /var/www/html/vendor
Run Code Online (Sandbox Code Playgroud)

构建和运行它的结果是一个/var/www/html没有vendor/我期望的目录的目录。

我的猜测是,这是因为docker-compose.yml服务定义中指定的卷实际上发生COPY --from似乎合乎逻辑的语句之后。但是我该如何解决这个问题?我仍然想在这里使用卷而不是ADDorCOPY命令。

atl*_*ine 5

您可以结合bind mounts&volume来制定您的目标,这是一个供您参考的最小示例:

docker-compose.yaml:

version: "3"

services:
  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    volumes:
      - my_folder:/var/www/html/vendor
      - .:/var/www/html

volumes:
  my_folder:
Run Code Online (Sandbox Code Playgroud)

码头工人/应用程序/Dockerfile:

FROM composer AS php_builder
COPY . /app
#RUN composer install --no-dev
RUN mkdir -p vendor && echo "I'm dependency!" > vendor/dependencies.txt

FROM php:7.1-fpm
COPY --from=php_builder /app/vendor /var/www/html/vendor
Run Code Online (Sandbox Code Playgroud)

结果:

shubuntu1@shubuntu1:~/test$ ls
docker  docker-compose.yaml  index.php
shubuntu1@shubuntu1:~/test$ docker-compose up -d
Creating network "test_default" with the default driver
Creating test_app_1 ... done
shubuntu1@shubuntu1:~/test$ docker exec -it test_app_1 /bin/bash
root@bf59d8684581:/var/www/html# ls
docker  docker-compose.yaml  index.php  vendor
root@bf59d8684581:/var/www/html# cat vendor/dependencies.txt
I'm dependency!
Run Code Online (Sandbox Code Playgroud)

从上面的执行中,可以看到dependencies.txt第一阶段生成的Dockerfilestill可以在容器中看到,volume只是docker自己管理数据,而bind mounts让你有机会自己管理数据。