Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy build files from one container to another or host on docker

I am trying to dockerize application where I have a php backend and vuejs frontend. Backend is working as I expect however after running npm run build within the frontend container, I need to copy build files from dist folder to nginx container or to host and then use volume to bring those files to nginx container.

I tried to use named volume

services:
  frontend:
  .....
  volumes:
  - static:/var/www/frontend/dist

 nginx:
  .....
  volumes:
  - static:/var/www/frontend/dist

volumes:
  static:

I also tried to do following as suggested on here to bring back dist folder to host

services:
  frontend:
  .....
  volumes:
  - ./frontend/dist:/var/www/frontend/dist

However none of the above options is working for me. Below is my docker-compose.yml file and frontend Dockerfile

version: "3"

services:

  database:
   image: mysql:5.7.22
   .....

  backend:
    build:
      context: ./docker/php
      dockerfile: Dockerfile
    .....

  frontend:
    build:
      context: .
      dockerfile: docker/node/Dockerfile
      target: 'build-stage'
    container_name: frontend
    stdin_open: true
    tty: true
    volumes:
      - ./frontend:/var/www/frontend

  nginx:
    build:
      context: ./docker/nginx
      dockerfile: Dockerfile
    container_name: nginx
    restart: unless-stopped
    ports:
      - 80:80
    volumes:
      - ./backend/public:/var/www/backend/public:ro
      - ./frontend/dist:/var/www/frontend/dist:ro
    depends_on:
      - backend
      - frontend

Frontend Dockerfile

# Develop stage
FROM node:lts-alpine as develop-stage
WORKDIR /var/wwww/frontend
COPY /frontend/package*.json ./

RUN npm install
COPY /frontend .

# Build stage
FROM develop-stage as build-stage
RUN npm run build
like image 347
user4676307 Avatar asked Oct 25 '25 01:10

user4676307


1 Answers

You can combine the frontend image and the Nginx image into a single multi-stage build. This basically just involves copying your docker/node/Dockerfile as-is into the start of docker/nginx/Dockerfile, and then COPY --from=build-stage into the final image. You will also need to adjust some paths since you'll need to make the build context be the root of your project.

# Essentially what you had in the question
FROM node:lts AS frontend
WORKDIR /frontend
COPY frontend/package*.json .
RUN npm install
COPY frontend .
RUN npm run build

# And then assemble the Nginx image with content
FROM nginx
COPY --from=frontend /frontend/dist /var/www/html

Once you've done this, you can completely delete the frontend container from your docker-compose.yml file. Note that it never did anything – the image didn't declare a CMD, and the docker-compose.yml didn't provide a command: to run either – and so this shouldn't really change your application.

You can use a similar technique to copy the static files from your PHP application into the Nginx proxy. When all is said and done, this leaves you with a simpler docker-compose.yml file:

version: "3.8"    
services:
  database:
   image: mysql:5.7.22
   .....

  backend:
    build: ./docker/php # don't need to explicitly name Dockerfile
    # note: will not need volumes: to export files
    .....

  # no frontend container any more

  nginx:
    build:
      context: . # because you're COPYing files from other components
      dockerfile: docker/nginx/Dockerfile
    restart: unless-stopped
    ports:
      - 80:80
    # no volumes:, everything is built into the image
    depends_on:
      - backend

(There are two practical problems with trying to share content using Docker named volumes. The first is that volumes never update their content once they're created, and in fact hide the content in their original image, so using volumes here actually causes changes in your source code to be ignored in favor of arbitrarily old content. In environments like Kubernetes, the cluster doesn't even provide the copy-on-first-use that Docker has, and there are significant limitations on how files can be shared between containers. This works better if you build self-contained images and don't try to share files.)

like image 170
David Maze Avatar answered Oct 26 '25 16:10

David Maze