【问题标题】:How to copy build files from one container to another or host on docker如何将构建文件从一个容器复制到另一个容器或 docker 上的主机
【发布时间】:2021-03-11 20:37:16
【问题描述】:

我正在尝试对具有 php 后端和 vuejs 前端的应用程序进行 dockerize。后端按我的预期工作,但是在前端容器中运行npm run build 后,我需要将构建文件从 dist 文件夹复制到 nginx 容器或托管,然后使用卷将这些文件带到 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

【问题讨论】:

    标签: node.js docker vue.js nginx docker-compose


    【解决方案1】:

    您可以将前端映像和 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
    

    完成此操作后,您可以从 docker-compose.yml 文件中完全删除 frontend 容器。请注意,它从来没有做任何事情——图像没有声明CMDdocker-compose.yml 也没有提供command: 来运行——所以这不应该真正改变你的应用程序。

    您可以使用类似的技术将静态文件从您的 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 所具有的首次使用时复制,并且文件的存储方式存在很大限制在容器之间共享。如果您构建独立的图像并且不尝试共享文件,这会更好。)

    【讨论】:

    • 感谢您的回答和建议。您提供的解决方案肯定适用于生产。然而,我想将前端容器分开的原因是允许我通过简单地针对开发阶段使用相同的 Dockerfile 进行开发,从我的 docker-compose.yml 运行 npm run serve 命令并绑定端口 8080。无论如何我请问您的建议可以做到这一点吗?
    • 我会使用 Webpack 的代理模式来指向这个容器堆栈来处理浏览器应用程序不直接提供的东西,然后在主机节点安装中使用 npm run dev
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 2014-05-19
    • 1970-01-01
    相关资源
    最近更新 更多