在单台服务器上部署前后端应用(如前端 Vue/React + 后端 Node.js/Java/Python 等),虽简化了基础设施,但需谨慎处理多个关键配置问题,否则易出现访问异常、安全风险、性能瓶颈或维护困难。以下是核心注意事项及实践建议:
一、端口与网络配置
-
避免端口冲突:
- 前端通常通过 Nginx/Apache X_X到
80/443(HTTP/HTTPS);后端服务应监听非特权端口(如3000,8080,9001),禁止直接暴露在 80/443 上(除非用 root 运行,不推荐)。 - ✅ 正确示例:Nginx 监听
80,反向X_X/api/到http://127.0.0.1:8080;静态资源由 Nginx 直接服务。
- 前端通常通过 Nginx/Apache X_X到
-
绑定地址安全:
- 后端服务应绑定
127.0.0.1:8080(仅本地可访问),禁止0.0.0.0:8080暴露到公网(除非有明确需求且配了防火墙)。 - ❌ 错误:
app.listen(8080)→ 默认可能绑定0.0.0.0;✅ 应显式写app.listen(8080, '127.0.0.1')。
- 后端服务应绑定
二、反向X_X配置(Nginx 是事实标准)
-
解决跨域问题(核心!):
前端构建后是静态文件(无 CORS 头),后端 API 需通过 Nginx 统一路径X_X,避免浏览器跨域拦截:server { listen 80; server_name your-domain.com; # 前端静态资源 location / { root /var/www/frontend/dist; try_files $uri $uri/ /index.html; # 支持 Vue Router history 模式 } # API X_X(关键:前端请求 /api/xxx → 后端) location /api/ { proxy_pass http://127.0.0.1:8080/; # 注意末尾 /,避免路径拼接错误 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-Proto $scheme; } } - 超时与缓冲区调优(尤其上传大文件或长连接):
proxy_connect_timeout 60; proxy_send_timeout 120; proxy_read_timeout 120; client_max_body_size 50M; # 允许上传大文件
三、前后端通信与环境适配
-
前端 API 基地址(Base URL):
- 开发时:
http://localhost:8080/api - 生产时:必须改为相对路径
/api/(依赖 Nginx X_X),而非硬编码后端 IP/端口。 - ✅ 推荐:Vue 中
axios.defaults.baseURL = '/api';React 中fetch('/api/users')。
- 开发时:
-
CORS 配置(备用方案,非首选):
若暂未配 Nginx,后端需开启 CORS(仅限开发/测试),但生产环境务必禁用 CORS,改用X_X(更安全、符合同源策略本意)。
四、安全加固(单机≠可忽视安全)
- HTTPS 强制启用:
使用 Let’s Encrypt(certbot)免费签发证书,Nginx 配置 HTTPS 并重定向 HTTP → HTTPS。 - 防火墙限制:
ufw allow OpenSSH ufw allow 'Nginx Full' # 80/443 ufw deny 8080 # 禁止外部直连后端端口 ufw enable - 后端服务权限最小化:
- 后端进程不要用 root 运行(如 Node.js 用
pm2 start app.js --uid nobody); - 静态资源目录(
/var/www/frontend/dist)设为只读,属主为www-data。
- 后端进程不要用 root 运行(如 Node.js 用
五、进程管理与稳定性
-
后端守护进程:
- Node.js:用
pm2(支持日志、重启、监控); - Java:用
systemdservice 或supervisord; - Python:用
gunicorn+systemd。 - ✅ 示例(pm2):
pm2 start app.js --name "backend" --env production pm2 startup # 生成开机自启脚本 pm2 save
- Node.js:用
-
前端静态服务:
- 不要用
serve -s或http-server长期运行(无守护、无日志、无健康检查); - ✅ 始终由 Nginx/Apache 托管静态文件(高性能、缓存、压缩、安全)。
- 不要用
六、资源与性能优化
- 静态资源缓存:
Nginx 配置强缓存(针对js/css/img):location ~* .(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } - Gzip/Brotli 压缩:
在 Nginx 中启用,减小传输体积(尤其 JS/CSS)。 - 内存与 CPU 监控:
单机部署需警惕资源争抢(如前端构建占用大量内存影响后端),建议:- 设置
pm2内存限制:pm2 start app.js --max-memory-restart 500M; - 使用
htop/netdata实时监控。
- 设置
七、日志与可观测性
- 分离日志:
- Nginx:
access.log/error.log(按天轮转); - 后端:输出到文件(如
pm2 logs或systemd journalctl -u myapp); - ❌ 避免前端 console.log 污染后端日志。
- Nginx:
- 错误追踪:
前端接入 Sentry,后端记录结构化错误(如winston+pino),便于定位问题。
八、部署与维护规范
- 自动化部署:
使用rsync+ssh脚本 或 GitHub Actions 自动同步前端 dist、重启后端(避免手动操作失误)。 - 版本隔离:
- 前端:
/var/www/frontend/v1.2.0/+ 符号链接current → v1.2.0; - 后端:Git tag + 构建产物独立目录,避免覆盖运行中进程。
- 前端:
- 备份策略:
定期备份 Nginx 配置、SSL 证书、数据库(如有)、关键日志。
⚠️ 常见踩坑总结
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 前端白屏,控制台报 404 | vue-router history 模式未配 try_files |
Nginx 中加 try_files $uri $uri/ /index.html; |
| API 返回 502 Bad Gateway | 后端未启动 / 端口不对 / proxy_pass 少 / |
检查 ps aux | grep 8080、curl -v http://127.0.0.1:8080/health、Nginx 日志 |
| 登录后刷新 404 | 后端未处理前端路由(如 /user/profile) |
✅ Nginx X_X所有非 API 请求到 index.html(见上 try_files) |
| HTTPS 下混合内容(Mixed Content) | 前端硬编码 http:// 请求资源 |
全部使用相对协议 // 或 /,或确保后端返回 X-Forwarded-Proto: https |
✅ 终极建议:
把 Nginx 当作唯一的入口网关 —— 它负责 SSL 终止、负载均衡(未来扩展)、WAF(可选)、缓存、日志、安全头(
X-Content-Type-Options,Strict-Transport-Security)等。前后端只需专注业务逻辑,无需操心网络细节。
如需,我可为你提供:
- 完整的 Nginx + Vue + Express 部署配置模板
- systemd 服务文件示例(Java/Python)
- 安全加固 checklist(含 CIS 基线)
- 自动化部署脚本(Bash/GitHub Actions)
欢迎随时提出具体技术栈(如 “Vue3 + Spring Boot” 或 “React + Django”),我可给出定制化方案。
云小栈