Home > Enterprise >  Docker: Shared volume when build
Docker: Shared volume when build

Time:11-24

I have this files:

docker-compose.yml (shortened):

version: '3.7'
services: 
  php-fpm:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
      target: dev
    volumes:
      - .:/app
  frontend:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
      target: frontend
    volumes:
      - .:/app

docker/php/Dockerfile (shortened):

FROM alpine:3.13 AS frontend
WORKDIR /app
COPY . .
RUN apk add npm
RUN npm install
RUN npx webpack -p --color --progress

FROM php:7.4-fpm AS dev
ENTRYPOINT ["docker-php-entrypoint"]
WORKDIR /app
COPY ./docker/php/www-dev.conf /usr/local/etc/php-fpm.d/www.conf
CMD ["php-fpm"]

I want to use all what building in frontend (as I understood at the stage build at this time volumes are not available) in php-fpm container, but I get something like this: file_get_contents(/app/static/frontend.version): failed to open stream.

How I can do this? I don't understand very well in Docker and the only solution I have is to move build script to php-fpm container.

CodePudding user response:

You need to delete the volumes: in your docker-compose.yml file. They replace the entire contents of the image's /app directory with content from the host, which means everything that gets done in the Dockerfile gets completely ignored.

The Dockerfile you show uses a setup called a multi-stage build. The important thing you can do with this is build the first part of your image using Node, then COPY --from=frontend the static files into the second part. You do not need to declare a second container in docker-compose.yml to run the first stage, the build sequence runs this automatically. This at a minimum looks like

COPY --from=frontend /app/build ./static

You will also need to COPY the rest of your application code into the image.

If you move the Dockerfile up to the top of your project's source tree, then the docker-compose.yml file becomes as simple as

version: '3.8'
services:
  php-fpm:
    build: .  # default Dockerfile, default target (last stage)
    # do not overwrite application code with volumes:
  # no separate frontend: container

But you've put a little bit more logic in the Dockerfile. I might write:

FROM node:lts AS frontend  # use a prebuilt Node image
WORKDIR /app
COPY package*.json .       # install dependencies first to save time on rebuild
RUN npm install
COPY . .                   # (or a more specific subdirectory?)
RUN npx webpack -p --color --progress

FROM php:7.4-fpm AS dev
WORKDIR /app
COPY . .                   # (or a more specific subdirectory?)
COPY --from=frontend /app/build ./static
COPY ./docker/php/www-dev.conf /usr/local/etc/php-fpm.d/www.conf
# don't need to repeat unmodified ENTRYPOINT/CMD from base image
  • Related