我正在尝试对我有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
你可以将前端图像和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
完成此操作后,你可以frontend
从docker-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拥有的首次使用时复制功能,并且在容器之间共享文件的方式受到很大限制。如果你构建独立的图像并且不尝试共享文件,则效果更好。)
感谢您的回答和建议。您提供的解决方案肯定可以用于生产。但是,我想将前端容器分开的原因是,通过简单地定位到开发阶段,即可从docker-compose.yml中运行npm run serve命令并绑定端口8080,从而使我可以使用相同的Dockerfile进行开发。可以通过您的建议实现这一目标?
我将使用Webpack的代理模式指向该容器堆栈,以查找浏览器应用程序不直接提供服务的内容,然后再指向
npm run dev
主机Node安装。