我有一个通过 docker-compose 运行的功能性全栈应用程序。奇迹般有效。唯一的问题是团队必须重建整个应用程序以反射(reflect)更改。这意味着用 docker-compose down
把整个事情搞下来。
我正在寻求帮助以更新以下文件以允许热重载 或简单地启用浏览器刷新以获取 UI 更改
注意事项:
- 我有“dev”和“prod”npm 脚本。两者的行为都与生产时一样(当前生成一个静态构建文件夹并指向它)
任何帮助将不胜感激:)
package.json
{
"name": "politicore",
"version": "1.0.1",
"description": "Redacted",
"repository": "Redacted",
"author": "Redacted",
"license": "LicenseRef-LICENSE.MD",
"private": true,
"engines": {
"node": "10.16.3",
"yarn": "YARN NO LONGER USED - use npm instead."
},
"scripts": {
"dev": "docker-compose up",
"dev-force": "docker-compose up --build --force-recreate",
"dev-force-d": "docker-compose up --build --force-recreate -d",
"prod-up": "docker-compose -f docker-compose-prod.yml up",
"prod-up-force": "docker-compose -f docker-compose-prod.yml up --build --force-recreate",
"prod-up-force-d": "docker-compose -f docker-compose-prod.yml up --build --force-recreate -d",
"dev-down": "docker-compose down",
"dev-down-remove": "docker-compose down --remove-orphans",
"prod-down": "docker-compose down",
"prod-down-remove": "docker-compose down --remove-orphans"
}
}
nginx 开发配置文件
server {
listen 80;
listen 443;
server_name MyUrl.com www.MyUrl.com;
server_tokens off;
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-Permitted-Cross-Domain-Policies master-only;
add_header Referrer-Policy same-origin;
add_header Expect-CT 'max-age=60';
add_header Feature-Policy "accelerometer none; ambient-light-sensor none; battery none; camera none; gyroscope none;";
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /graphql {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_pass http://api:5000;
proxy_redirect default;
}
}
docker-compose 开发文件
version: '3.6'
services:
api:
build:
context: ./services/api
dockerfile: Dockerfile-dev
restart: always
volumes:
- './services/api:/usr/src/app'
- '/usr/src/app/node_modules'
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
env_file:
- common/.env
client:
build:
context: ./services/client
dockerfile: Dockerfile-dev
restart: always
volumes:
- './services/client:/usr/src/app'
- '/usr/src/app/node_modules'
ports:
- 80:80
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
depends_on:
- api
stdin_open: true
客户端服务 dockerfile
FROM node:10 as builder
WORKDIR /usr/src/app
COPY package.json /usr/src/app/package.json
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
COPY nginx/dev.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
API dockerfile(开发和生产)
FROM node:10
WORKDIR /usr/src/app
COPY package.json /usr/src/app/package.json
RUN npm install
CMD ["npm", "start"]
文件 TreeMap 片
最佳答案
据我了解,您的 nginx 文件定义了 2 个服务区域:location/
和 location/graphql
。
第一个 (location/
) 是从容器内的 /usr/share/nginx/html
提供静态文件。这些文件是在您的 docker 构建期间创建的。由于这些是在多阶段 docker 构建中生成的,因此您需要更改策略。以下是可能有助于指导您的几个选项。
选项 1
一种选择是在本地构建并安装一个卷。
- 在你的盒子上执行
npm run build
(甚至可以使用文件观察器在 *.js 文件更改时执行构建 - 添加
- ./build:/usr/share/nginx/html
到client
服务的卷列表
这里的权衡是您必须放弃完全 dockerized 的构建(如果这对您和您的团队非常重要的话)。
选项 2
利用热加载节点服务器进行本地开发,并为生产环境构建 docker 镜像。很难从文件中判断客户端是 react、angular、vuejs 等,但通常它们具有运行本地开发服务器的模式。
这里的权衡是您在本地运行与在生产环境中运行不同。
选项 3
将 nginx 和 nodejs 合并为一个 docker 镜像,内部热加载。
- 构建包含nodejs和nginx的本地docker镜像
- (您已经将卷安装到应用程序源文件的
client
中) - 设置镜像以在每次挂载卷中的文件更改时在容器内运行
npm run build
这里的权衡是您可能在一个 docker 容器中运行超过 1 个进程(这是一个很大的禁忌)。
选项 4
选项 3 的变体,您运行 2 个 docker 容器。
- 声明一个顶级卷
client_build
- >
volumes: - client_build:
- >
- 在
docker-compose
中创建一个包含 2 个卷的 docker 服务- ./services/client:/usr/src/app
- client_build:/usr/src/app/build
- 将构建卷添加到您的
client
服务:- client_build:/usr/share/nginx/html
- 确保当该目录更改时 nginx 热重载
关于Docker-Compose、NGINX 和热重载配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64001499/