Warm tip: This article is reproduced from serverfault.com, please click

node.js-如何将构建文件从一个容器复制到另一个或在Docker上托管

(node.js - How to copy build files from one container to another or host on docker)

发布于 2020-11-29 20:28:29

我正在尝试对我有php后端和vuejs前端的应用程序进行dockerize。后端按预期运行npm run build但是在前端容器中运行后,我需要将构建文件从dist文件夹复制到nginx容器或主机,然后使用volume将这些文件带入nginx容器。

我想使用命名卷

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

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

volumes:
  static:

我也尝试按照此处的建议执行以下操作以将dist文件夹重新带回主机

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

但是,以上选项均不适用于我。以下是我的docker-compose.yml文件和前端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

前端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
Questioner
user4676307
Viewed
11
David Maze 2020-11-30 05:24:53

你可以将前端图像和Nginx图像合并到一个多阶段构建中。这基本上只涉及将你的docker/node/Dockerfile原样复制到的开头docker/nginx/Dockerfile,然后复制COPY --from=build-stage到最终映像。你还需要调整一些路径,因为你需要使构建上下文成为项目的根源。

# 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

完成此操作后,你可以frontenddocker-compose.yml文件中完全删除该容器请注意,它从不执行任何操作–映像未声明a CMD,并且docker-compose.yml也未提供command:要运行的a –因此,这实际上不应更改你的应用程序。

你可以使用类似的技术将静态文件从PHP应用程序复制到Nginx代理中。说完所有步骤后,你将得到一个简单的docker-compose.yml文件:

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

(尝试使用Docker命名卷共享内容存在两个实际问题。第一个问题是,卷一旦创建就永远不会更新其内容,并且实际上会将内容隐藏在其原始映像中,因此在此处使用卷实际上会导致更改在使用任意旧内容的情况下,你的源代码将被忽略。在Kubernetes之类的环境中,集群甚至不提供Docker拥有的首次使用时复制功能,并且在容器之间共享文件的方式受到很大限制。如果你构建独立的图像并且不尝试共享文件,则效果更好。)