努力
加油

如何在同一个云服务器上部署两个不同的应用?

在单台云服务器上部署两个不同的应用,核心思路其实就三个:隔离环境、区分端口/域名、资源管理。

别一上来就想搞什么复杂的微服务架构,对于大多数场景,尤其是初创项目或个人开发者,用最简单、最稳定、维护成本最低的方式才是王道。下面我把几种主流方案按“推荐程度”从高到低梳理一遍,你根据自己的技术栈和需求选。

方案一:Nginx 反向XX + 不同端口(最通用、最推荐)

这是目前互联网行业最标准的做法。不管你的应用是 Java (Spring Boot)、Python (Django/Flask)、Node.js 还是 Go,只要它们能监听本地端口,就能这么干。

原理:

  1. 应用 A 监听 localhost:8080
  2. 应用 B 监听 localhost:9000
  3. Nginx 作为入口,根据访问的域名或路径,把请求转发给对应的应用。

具体操作逻辑:

  1. 安装 Nginx:

    yum install nginx -y  # CentOS
    apt install nginx     # Ubuntu
  2. 配置 Nginx 反向XX:
    编辑 /etc/nginx/conf.d/app.conf(或者直接在 nginx.conf 里加 server 块):

    # 应用 A:通过域名访问
    server {
        listen 80;
        server_name app.example.com; # 假设你有这个域名并解析到服务器IP
    
        location / {
            proxy_pass http://127.0.0.1:8080; # 应用A的本地端口
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
    
    # 应用 B:通过子路径或另一个域名访问
    server {
        listen 80;
        server_name b.example.com; 
    
        location / {
            proxy_pass http://127.0.0.1:9000; # 应用B的本地端口
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
  3. 启动应用:
    确保你的两个应用分别运行在 8080 和 9000 端口。如果是 Java 项目,启动命令类似:

    java -jar app-a.jar --server.port=8080 &
    java -jar app-b.jar --server.port=9000 &

    建议配合 systemd 或 supervisor 来管理进程,防止应用挂了没人重启。

  4. 安全组配置:
    在云厂商控制台(阿里云、腾讯云等),只开放 80 端口 和 443 端口(如果配 HTTPS)。8080 和 9000 这种内部端口绝对不要对公网开放,否则直接裸奔,风险极大。

优点:

  • 兼容性好,任何语言都能用。
  • 可以统一做 HTTPS 证书管理(Let’s Encrypt + certbot 一键搞定)。
  • 可以做负载均衡、缓存、静态资源分离。

方案二:Docker Compose 多容器部署(现代化、易维护)

如果你希望环境隔离更彻底,不想让两个应用的依赖库互相干扰(比如一个要 Python 3.8,一个要 Python 3.11),Docker 是最佳选择。

原理:
每个应用跑在一个独立的 Docker 容器里,容器之间网络隔离,对外通过端口映射暴露。

操作步骤:

  1. 安装 Docker 和 Docker Compose。

  2. 编写 docker-compose.yml:

    version: '3'
    services:
      app-a:
        build: ./app-a
        ports:
          - "8080:8080"  # 内部端口:外部映射端口
        environment:
          - DB_HOST=mysql-container
    
      app-b:
        build: ./app-b
        ports:
          - "9000:9000"
        environment:
          - REDIS_HOST=redis-container
    
      mysql-container:
        image: mysql:5.7
        volumes:
          - db_data:/var/lib/mysql
    
    volumes:
      db_data:
  3. 启动:

    docker-compose up -d
  4. 同样需要 Nginx 做反向XX(可选但推荐):
    虽然你可以直接访问 IP:8080 和 IP:9000,但为了安全和统一管理,依然建议在宿主机装个 Nginx,把 80 端口的流量转发到容器的 8080 和 9000。

优点:

  • 环境隔离完美,避免“依赖地狱”。
  • 迁移方便,换个服务器只需拷贝代码和 compose 文件。
  • 资源限制方便(可以给每个容器设置 CPU/内存上限)。

方案三:同一应用框架内的多实例(仅限同类应用)

如果你的两个应用是同一个技术栈,比如都是 Spring Boot 后端,或者都是 Node.js Express 应用,且业务逻辑耦合度不高,可以考虑让它们共享部分基础设施。

但这通常不推荐用于完全独立的应用,因为容易导致配置文件混乱、日志混在一起、监控难分。除非你是做 SaaS 多租户模式,否则别走这条路。


关键注意事项(避坑指南)

  1. 端口冲突检测:
    在部署前,先执行 netstat -tlnp 或 ss -tlnp,看看服务器上有没有其他服务占用了你想用的端口(比如 MySQL 默认 3306,Redis 默认 6379)。

  2. 防火墙与安全组:

    • 云厂商安全组:只开 80/443 SSH(22)。
    • 系统防火墙:CentOS 用 firewalld,Ubuntu 用 ufw,确保只放行必要端口。
    • 应用绑定地址:应用启动时,务必绑定 0.0.0.0 而不是 127.0.0.1,否则 Nginx 反向XX可能连不上(取决于配置方式,但通常绑定 0.0.0.0 更安全可控)。
  3. 资源规划:
    一台服务器跑两个应用,CPU 和内存是有限的。如果两个应用都吃资源,很容易 OOM(内存溢出)导致双双挂掉。

    • 使用 htop 实时监控。
    • 给应用设置 JVM 堆大小(Java)、Node.js 内存限制等。
    • 如果预计流量增长,尽早考虑拆分到两台服务器或使用 Kubernetes。
  4. 日志管理:
    不要把两个应用的日志打到同一个文件里!否则排查问题时你会疯掉。

    • Nginx 有 access.log 和 error.log。
    • 应用本身最好配置独立的日志输出路径,如 /var/log/app-a/ 和 /var/log/app-b/。
    • 可以使用 journalctl -u service-name 查看 systemd 管理的服务日志。
  5. HTTPS 证书:
    现在没有 HTTPS 的网站用户体验极差,而且会被浏览器标记为“不安全”。

    • 推荐使用 Certbot 自动申请 Let’s Encrypt 免费证书。
    • 在 Nginx 中配置 SSL 终止,这样后端应用就不用关心加密解密,减轻负担。

总结建议

  • 新手/简单项目:直接用 Nginx 反向XX + 不同端口。最简单,最快上手。
  • 正式生产环境/多语言混合:用 Docker Compose + Nginx。隔离好,维护方便,扩展性强。
  • 切记:永远不要让应用直接暴露在公网端口,一定要经过 Nginx 或类似网关层。

按照这个思路去配置,基本不会出错。如果遇到具体的 Nginx 配置报错或 Docker 启动失败,再针对性地查日志解决。