前端项目部署时,多个应用如何共用一台服务器?

在前端项目部署中,多个应用共用一台服务器是极其常见的场景,核心思路只有两个词:反向X_X 和 端口隔离。

作为技术人员,我们通常不会让多个前端应用直接监听不同的端口暴露给公网(比如 http://IP:8081, http://IP:8082),因为这样既不美观也不利于管理。最主流、最稳健的方案是使用 Nginx 作为反向X_X服务器,通过域名或路径将请求分发到不同的后端服务或本地静态资源目录。

以下是几种主流的实施方案,按推荐程度排序:

方案一:基于域名的虚拟主机(Virtual Host)—— 最推荐

这是生产环境中最标准的做法。假设你有一台云服务器(如阿里云 ECS、腾讯云 CVM),拥有一个主域名 example.com。

  1. 前提条件:

    • 服务器已安装 Nginx。
    • 你有多个子域名,例如 app1.example.com 和 app2.example.com,并已解析到该服务器 IP。
    • 你的前端项目已经构建好(npm run build),生成了 dist 或 build 文件夹。
  2. Nginx 配置示例 (/etc/nginx/conf.d/default.conf):

# 应用 1:app1.example.com
server {
    listen 80;
    server_name app1.example.com;

    root /var/www/app1/dist; # 指向应用1的构建产物目录
    index index.html;

    location / {
        try_files $uri $uri/ /index.html; # Vue/React 等单页应用必须配置,防止刷新404
    }

    # 可选:配置 HTTPS(使用 Let's Encrypt 免费证书)
    # listen 443 ssl;
    # ssl_certificate /path/to/cert.pem;
    # ssl_certificate_key /path/to/cert.key;
}

# 应用 2:app2.example.com
server {
    listen 80;
    server_name app2.example.com;

    root /var/www/app2/dist; # 指向应用2的构建产物目录
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}
  1. 优点:
    • 结构清晰,每个应用独立管理。
    • 易于扩展,新增应用只需加一个 server 块。
    • 支持 HTTPS,安全性高。
    • 对 SEO 友好(如果使用 SSR)。

方案二:基于路径的反向X_X(Path-based Routing)

如果你只有一个域名(如 example.com),但想部署多个应用,可以通过 URL 路径来区分。

  • example.com/admin -> 管理后台应用
  • example.com/user -> 用户前台应用
  1. Nginx 配置示例:
server {
    listen 80;
    server_name example.com;

    # 管理后台应用
    location /admin {
        alias /var/www/admin-app/dist; # 注意用 alias 而不是 root
        index index.html;
        try_files $uri $uri/ /admin/index.html; # 注意最后的路径要匹配
    }

    # 用户前台应用
    location /user {
        alias /var/www/user-app/dist;
        index index.html;
        try_files $uri $uri/ /user/index.html;
    }
}
  1. 注意事项:
    • 前端路由配置:你需要确保每个前端应用在构建时,publicPath 或 base 配置正确。例如,在 Vite 中设置 base: '/admin/',在 Webpack 中设置 output.publicPath: '/admin/'。否则,静态资源(JS/CSS)加载会失败。
    • 复杂度较高:需要仔细处理路径映射,容易出错。

方案三:Docker + Nginx —— 现代化运维首选

如果你希望实现“一次构建,到处运行”,并且便于版本管理和隔离,推荐使用 Docker。

  1. 为每个应用编写 Dockerfile:
# Dockerfile for App1
FROM nginx:alpine
COPY ./dist /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
  1. 编排服务 (docker-compose.yml):
version: '3'
services:
  app1:
    build: ./app1
    ports:
      - "8081:80"
    volumes:
      - ./app1/nginx.conf:/etc/nginx/conf.d/default.conf

  app2:
    build: ./app2
    ports:
      - "8082:80"
    volumes:
      - ./app2/nginx.conf:/etc/nginx/conf.d/default.conf

  nginx-proxy:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./proxy-nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app1
      - app2
  1. 反向X_X Nginx 配置 (proxy-nginx.conf):
upstream app1_backend {
    server app1:80;
}

upstream app2_backend {
    server app2:80;
}

server {
    listen 80;

    location / {
        proxy_pass http://app1_backend;
    }

    location /api {
        proxy_pass http://app2_backend;
    }
}

说明:这里为了简化,展示了两个应用分别监听不同内部端口,由外部 Nginx 统一转发。更复杂的场景可以使用 Traefik 或 Consul Template 自动发现服务。


关键注意事项与最佳实践

  1. 静态资源缓存策略:
    前端项目通常包含大量 JS/CSS 文件,且文件名带有 Hash(如 app.a1b2c3.js)。务必在 Nginx 中配置长期缓存,以减少服务器压力和提升用户体验:

    location ~* .(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
  2. SPA 应用的 history 模式:
    如果你的前端框架(Vue Router, React Router)使用了 history 模式,必须配置 try_files,将所有非静态资源的请求重定向到 index.html,交由前端路由处理。否则,用户直接访问 /about 会返回 404。

  3. 安全加固:

    • 不要直接暴露服务器 IP 和端口。
    • 使用防火墙(如阿里云安全组、腾讯云云防火墙)只开放 80/443 端口。
    • 配置 HTTPS 证书,避免浏览器提示“不安全”。
    • 定期更新 Nginx 版本,修复已知漏洞。
  4. 监控与维护:

    • 使用 PM2 或 systemd 管理 Nginx 进程,确保崩溃后自动重启。
    • 配置日志轮转(logrotate),避免 access.log 和 error.log 无限增长占满磁盘。
  5. 国内云厂商特定建议:

    • 阿里云:建议使用 ALB(应用型负载均衡) 替代自建 Nginx,尤其在高并发场景下,ALB 支持基于域名的路由规则,无需手动维护配置文件,且自带 SSL 卸载能力。
    • 腾讯云:类似地,可使用 CLB(经典负载均衡) 或 TKE(容器服务) 进行部署。
    • 华为云:推荐 ELB(弹性负载均衡)。

总结

对于大多数中小型项目,Nginx + 多域名虚拟主机 是最简单、高效、易维护的方案。如果追求自动化和微服务架构,则选择 Docker + Nginx Proxy。无论哪种方式,核心都是利用反向X_X技术,将用户的 HTTP 请求根据域名或路径,精准地转发到服务器上对应的应用实例。

未经允许不得转载:CLOUD云枢 » 前端项目部署时,多个应用如何共用一台服务器?