Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker compose volume overrides COPY in multi-stage build

My goal is to get php dependencies in one stage of a docker file then copy those dependencies to the next stage (the vendor/ dir). However, once a volume is specified in docker-compose.yml that overrides the COPY statement as if it never happened.

docker-compose.yml

version: "3"

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

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

The result of building and running this is a /var/www/html directory that doesn't have the vendor/ directory as I'd expect.

My guess is that this is because the volume specified in the docker-compose.yml service definition actually happens after the COPY --from statement which seems to be logical. But how do I get around this? I'd still like to use a volume here instead of an ADD or COPY command.

like image 665
peter Avatar asked Jul 16 '19 21:07

peter


1 Answers

You can combine bind mounts & volume to make your aim, a minimal example for your reference:

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:

docker/app/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

Results:

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!

From above execution, you can see the dependencies.txt which generated in the first stage of Dockerfile still could be seen in the container, volume just manage the data by docker itself, while bind mounts give you chance to manage data for yourself.

like image 101
atline Avatar answered Oct 11 '22 06:10

atline