多版本Node环境下Vue/React应用Docker构建结果导出至宿主机及Nginx子域名部署方案问询
多版本Node环境下Vue/React应用Docker构建结果导出至宿主机及Nginx子域名部署方案问询
嘿,我来帮你梳理下这个问题的解决思路,核心就是搞定容器构建产物同步到宿主机,再配合Nginx子域名转发的配置。
首先说你最关心的:怎么把容器里的构建文件夹弄到宿主机的/var/www/project_name?有两种靠谱的方式,看你需求选:
方法一:绑定挂载自动同步(推荐,适合自动化构建)
这种方式最省心,在docker-compose.yml里给每个构建服务加个挂载,直接把宿主机的目标目录和容器内的构建产物目录绑定,容器执行npm run build后,产物会自动同步到宿主机。
举个例子,假设你的Vue项目构建产物在dist目录,React项目在build目录,调整你的docker-compose.yml:
version: "3.1" services: redis: restart: always image: redis:alpine container_name: redis build-adminapp: build: adminapp/ container_name: adminapp working_dir: /var/www/adminapp volumes: # 挂载本地项目代码到容器,让容器能读取源码进行构建 - ./adminapp:/var/www/adminapp # 把容器内的构建产物目录和宿主机目标目录绑定,自动同步 - /var/www/adminapp:/var/www/adminapp/dist # 启动容器时执行构建命令 command: sh -c "npm install && npm run build" build-clientapp: build: clientapp/ container_name: clientapp working_dir: /var/www/clientapp volumes: - ./clientapp:/var/www/clientapp # 如果是React项目,把dist改成build就行 - /var/www/clientapp:/var/www/clientapp/build command: sh -c "npm install && npm run build"
同时优化下你的Dockerfile,利用Docker缓存加快构建速度(比如先复制package.json装依赖,再复制源码):
adminapp/Dockerfile(Node 10)
FROM node:10-alpine WORKDIR /var/www/adminapp/ # 先复制依赖配置文件,利用缓存,只有package.json变化时才重新装依赖 COPY package*.json ./ RUN npm install # 再复制项目源码 COPY . . # 可以把构建命令写在这里,也可以用docker-compose的command覆盖 CMD ["npm", "run", "build"]
clientapp/Dockerfile(Node 12)
FROM node:12-alpine WORKDIR /var/www/clientapp/ COPY package*.json ./ RUN npm install COPY . . CMD ["npm", "run", "build"]
这样启动构建服务时,产物会自动同步到宿主机的/var/www/adminapp和/var/www/clientapp目录。
方法二:手动用docker cp复制(适合一次性构建)
如果不需要每次启动容器都构建,只是偶尔手动触发,可以先让容器完成构建,再把产物复制到宿主机:
- 先启动构建容器执行构建(
--rm会在执行完后自动删除容器):
docker-compose run --rm build-adminapp
- 然后把容器内的构建产物复制到宿主机:
# 假设adminapp的产物在dist目录 docker cp adminapp:/var/www/adminapp/dist /var/www/adminapp
这种方式适合临时构建,不需要长期挂载目录的场景。
接下来是Nginx子域名部署的配置
搞定构建产物同步后,就可以配置Nginx容器来根据子域名转发了:
- 先创建Nginx配置文件,比如
./nginx/conf.d/apps.conf:
# 子域名admin.yourdomain.com对应adminapp server { listen 80; server_name admin.yourdomain.com; # 指向宿主机同步过来的adminapp构建目录 root /usr/share/nginx/html/adminapp; index index.html; # Vue/React单页应用需要这个配置,处理路由跳转 location / { try_files $uri $uri/ /index.html; } } # 子域名client.yourdomain.com对应clientapp server { listen 80; server_name client.yourdomain.com; root /usr/share/nginx/html/clientapp; index index.html; location / { try_files $uri $uri/ /index.html; } }
- 在
docker-compose.yml里添加Nginx服务:
# 加到services里 nginx: image: nginx:alpine container_name: nginx-web restart: always ports: - "80:80" # 如果需要HTTPS,打开下面的端口并配置证书 # - "443:443" volumes: # 挂载宿主机的/var/www目录到Nginx的静态文件目录 - /var/www:/usr/share/nginx/html # 挂载自定义的Nginx配置文件 - ./nginx/conf.d:/etc/nginx/conf.d
最后,先启动构建服务完成产物同步,再启动Nginx服务:
# 执行构建 docker-compose up build-adminapp build-clientapp # 启动Nginx和Redis docker-compose up -d nginx redis
这样就能通过admin.yourdomain.com和client.yourdomain.com分别访问两个项目了。
备注:内容来源于stack exchange,提问作者Yarik Bezugly
相关产品推荐
相关产品推荐

