|
| 1 | +# Monorepo 项目的 Nginx 配置指南 |
| 2 | + |
| 3 | +## 简介 |
| 4 | + |
| 5 | +Monorepo(单一代码库)架构允许在一个代码仓库中管理多个相关项目。这种架构在前端开发中变得越来越流行,特别是对于组件库和微前端应用。本文将介绍如何配置 Nginx 来有效地部署和服务 Monorepo 项目。 |
| 6 | + |
| 7 | +## Monorepo 的 Nginx 配置挑战 |
| 8 | + |
| 9 | +在 Monorepo 中部署多个应用时,我们面临以下挑战: |
| 10 | + |
| 11 | +1. 多个子项目需要不同的路由规则 |
| 12 | +2. 静态资源的缓存策略需要统一管理 |
| 13 | +3. API 代理可能需要根据不同应用进行配置 |
| 14 | +4. 特殊连接(如 SSE)需要特定的 Nginx 设置 |
| 15 | + |
| 16 | +## 完整配置示例 |
| 17 | + |
| 18 | +以下是一个针对 Monorepo 项目的完整 Nginx 配置示例: |
| 19 | + |
| 20 | +```nginx |
| 21 | +server { |
| 22 | + listen 80; |
| 23 | + listen [::]:80; |
| 24 | + server_name localhost; |
| 25 | +
|
| 26 | + # 全局设置 |
| 27 | + client_max_body_size 600m; |
| 28 | + root /usr/share/nginx/html; |
| 29 | + index index.html index.htm; |
| 30 | +
|
| 31 | + # 全局缓存控制 - 针对不同内容类型调整缓存策略 |
| 32 | + # 静态资源可以缓存,动态内容避免缓存 |
| 33 | + location ~* \.(css|js)$ { |
| 34 | + access_log off; |
| 35 | + add_header Cache-Control "public, max-age=86400"; # 1天 |
| 36 | + } |
| 37 | +
|
| 38 | + location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { |
| 39 | + access_log off; |
| 40 | + add_header Cache-Control "public, max-age=604800"; # 7天 |
| 41 | + } |
| 42 | +
|
| 43 | + location ~* \.(html|htm)$ { |
| 44 | + add_header Cache-Control "no-cache, must-revalidate"; |
| 45 | + } |
| 46 | +
|
| 47 | + # 设置变量以减少重复 |
| 48 | + set $html_root "/usr/share/nginx/html"; |
| 49 | + set $api_server "http://172.0.0.1:60300"; |
| 50 | +
|
| 51 | + # 应用路由规则 - 使用正则简化配置 |
| 52 | + location ~ ^/app/ll-([^/]+)/(.*)$ { |
| 53 | + alias $html_root/$1/dist/$2; |
| 54 | + try_files $uri $uri/ /app/ll-$1/index.html; |
| 55 | +
|
| 56 | + # 启用gzip压缩 |
| 57 | + gzip on; |
| 58 | + gzip_min_length 1k; |
| 59 | + gzip_comp_level 6; |
| 60 | + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; |
| 61 | + } |
| 62 | +
|
| 63 | + # 平台或者首页特殊路由 |
| 64 | + location /app/ll-platform/ll/ { |
| 65 | + alias $html_root/platform/dist/ll/; |
| 66 | + try_files $uri $uri/ /index.html; |
| 67 | + } |
| 68 | +
|
| 69 | + # 默认重定向至平台或者首页 |
| 70 | + location = / { |
| 71 | + return 301 /app/ll-platform/ll/; |
| 72 | + } |
| 73 | +
|
| 74 | + # API 代理 |
| 75 | + location /api/app/ { |
| 76 | + proxy_pass $api_server/api/app/; |
| 77 | +
|
| 78 | + # 通用代理头设置 |
| 79 | + include /etc/nginx/proxy_params; |
| 80 | +
|
| 81 | + # 自定义超时设置 |
| 82 | + proxy_read_timeout 180s; |
| 83 | + proxy_connect_timeout 60s; |
| 84 | + proxy_send_timeout 60s; |
| 85 | +
|
| 86 | + # 跨域支持 |
| 87 | + add_header 'Access-Control-Allow-Origin' '*' always; |
| 88 | + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, PATCH' always; |
| 89 | + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always; |
| 90 | +
|
| 91 | + # OPTIONS 预检请求处理 |
| 92 | + if ($request_method = 'OPTIONS') { |
| 93 | + return 204; |
| 94 | + } |
| 95 | + } |
| 96 | +
|
| 97 | + # SSE 特殊代理配置 |
| 98 | + location /api/app/agent/chat/sse/ { |
| 99 | + proxy_pass $api_server/api/app/agent/chat/sse/; |
| 100 | +
|
| 101 | + # 必要的SSE代理设置 |
| 102 | + include /etc/nginx/proxy_params; |
| 103 | + proxy_http_version 1.1; |
| 104 | + proxy_set_header Connection ''; |
| 105 | + proxy_buffering off; |
| 106 | +
|
| 107 | + # 长连接支持 |
| 108 | + proxy_read_timeout 3600s; |
| 109 | + proxy_send_timeout 3600s; |
| 110 | + keepalive_timeout 65; |
| 111 | + keepalive_requests 100; |
| 112 | +
|
| 113 | + chunked_transfer_encoding on; |
| 114 | + proxy_cache off; |
| 115 | + add_header Cache-Control no-cache; |
| 116 | + } |
| 117 | +
|
| 118 | + # 错误页面 |
| 119 | + error_page 404 /404.html; |
| 120 | + error_page 500 502 503 504 /50x.html; |
| 121 | + location = /50x.html { |
| 122 | + root /usr/share/nginx/html; |
| 123 | + } |
| 124 | +
|
| 125 | + # 限制某些敏感文件的访问 |
| 126 | + location ~ /\.(?!well-known) { |
| 127 | + deny all; |
| 128 | + } |
| 129 | +} |
| 130 | +
|
| 131 | +# 建议在http块中(此配置外部)增加以下全局优化配置: |
| 132 | +# http { |
| 133 | +# # TCP优化 |
| 134 | +# sendfile on; |
| 135 | +# tcp_nopush on; |
| 136 | +# tcp_nodelay on; |
| 137 | +# |
| 138 | +# # 连接优化 |
| 139 | +# keepalive_timeout 65; |
| 140 | +# keepalive_requests 100; |
| 141 | +# |
| 142 | +# # 工作进程配置 |
| 143 | +# # worker_processes auto; |
| 144 | +# # worker_connections 1024; |
| 145 | +# |
| 146 | +# # GZIP全局设置 |
| 147 | +# gzip on; |
| 148 | +# gzip_min_length 1k; |
| 149 | +# gzip_comp_level 6; |
| 150 | +# gzip_types text/plain text/css application/json application/javascript text/xml application/xml; |
| 151 | +# gzip_vary on; |
| 152 | +# } |
| 153 | +``` |
| 154 | + |
| 155 | +## 配置说明 |
| 156 | + |
| 157 | +### 1. 静态资源缓存策略 |
| 158 | + |
| 159 | +针对不同类型的静态资源,我们设置了不同的缓存策略: |
| 160 | + |
| 161 | +- CSS 和 JS 文件缓存 1 天 |
| 162 | +- 图片和字体文件缓存 7 天 |
| 163 | +- HTML 文件不缓存,确保内容实时更新 |
| 164 | + |
| 165 | +```nginx |
| 166 | +location ~* \.(css|js)$ { |
| 167 | + access_log off; |
| 168 | + add_header Cache-Control "public, max-age=86400"; # 1天 |
| 169 | +} |
| 170 | +``` |
| 171 | + |
| 172 | +### 2. 多应用路由配置 |
| 173 | + |
| 174 | +使用正则表达式匹配不同应用的路由,并将请求重定向到对应的目录: |
| 175 | + |
| 176 | +```nginx |
| 177 | +location ~ ^/app/ll-([^/]+)/(.*)$ { |
| 178 | + alias $html_root/$1/dist/$2; |
| 179 | + try_files $uri $uri/ /app/ll-$1/index.html; |
| 180 | +
|
| 181 | + # 启用gzip压缩... |
| 182 | +} |
| 183 | +``` |
| 184 | + |
| 185 | +这个配置允许我们通过 URL 路径区分不同的应用,例如: |
| 186 | + |
| 187 | +- `/app/ll-project1/` 会指向 `/usr/share/nginx/html/project1/dist/` |
| 188 | +- `/app/ll-project2/` 会指向 `/usr/share/nginx/html/project2/dist/` |
| 189 | + |
| 190 | +### 3. API 代理配置 |
| 191 | + |
| 192 | +所有 API 请求通过 Nginx 代理到后端服务: |
| 193 | + |
| 194 | +```nginx |
| 195 | +location /api/app/ { |
| 196 | + proxy_pass $api_server/api/app/; |
| 197 | + # 其他代理设置... |
| 198 | +} |
| 199 | +``` |
| 200 | + |
| 201 | +特别是对于 SSE(Server-Sent Events)等特殊连接,我们需要进行特殊配置: |
| 202 | + |
| 203 | +```nginx |
| 204 | +location /api/app/agent/chat/sse/ { |
| 205 | + # SSE 特殊配置... |
| 206 | + proxy_buffering off; |
| 207 | + proxy_read_timeout 3600s; |
| 208 | + # 其他设置... |
| 209 | +} |
| 210 | +``` |
| 211 | + |
| 212 | +### 4. 全局 HTTP 优化 |
| 213 | + |
| 214 | +在 `http` 块中,我们建议添加以下优化配置: |
| 215 | + |
| 216 | +```nginx |
| 217 | +# TCP优化 |
| 218 | +sendfile on; |
| 219 | +tcp_nopush on; |
| 220 | +tcp_nodelay on; |
| 221 | +
|
| 222 | +# 连接优化 |
| 223 | +keepalive_timeout 65; |
| 224 | +keepalive_requests 100; |
| 225 | +
|
| 226 | +# GZIP全局设置 |
| 227 | +gzip on; |
| 228 | +gzip_min_length 1k; |
| 229 | +# 其他gzip设置... |
| 230 | +``` |
| 231 | + |
| 232 | +## Monorepo 项目的 Nginx 部署最佳实践 |
| 233 | + |
| 234 | +1. **使用变量减少配置重复**:通过设置变量(如 `$html_root`)来减少配置中的重复内容 |
| 235 | + |
| 236 | +2. **使用正则表达式简化路由**:针对多个类似的应用,使用正则表达式可以大幅简化配置 |
| 237 | + |
| 238 | +3. **分离关注点**:将静态资源缓存、API 代理、错误处理等配置分开管理 |
| 239 | + |
| 240 | +4. **启用 GZIP 压缩**:对于前端应用,启用 GZIP 压缩可以显著提高加载速度 |
| 241 | + |
| 242 | +5. **合理设置超时时间**:根据不同服务的特性(如 SSE)设置合适的超时时间 |
| 243 | + |
| 244 | +## 结论 |
| 245 | + |
| 246 | +在 Monorepo 项目中,一个精心配置的 Nginx 可以帮助我们高效地部署和管理多个应用。通过本文介绍的配置和最佳实践,你可以为你的 Monorepo 项目构建一个稳定、高效的部署环境。 |
| 247 | + |
| 248 | +--- |
| 249 | + |
| 250 | +希望这份配置指南对你的 Monorepo 项目有所帮助。如果你有任何问题或改进建议,欢迎讨论交流。 |
0 commit comments