You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Passenger的同域名多版本多Rails应用多租户部署方案问询

Hey there! 很高兴看到你已经上手Rails一个月还搞定了生产环境部署,这个多版本同域名部署的需求确实是Rails开发者常遇到的场景,用Passenger来实现完全可行,我给你梳理几个实用方案和关键步骤:

核心思路:基于Passenger的虚拟主机+路由/标识区分

不管是多版本应用还是多租户场景,核心都是让Passenger根据不同的请求规则,指向对应版本的Rails应用,同时保证各个应用的Ruby/Rails版本互相隔离。

方案1:同域名下通过子路径区分不同应用(比如 example.com/app1、example.com/app2)

这是同域名下最直观的部署方式,以Passenger+Nginx组合为例(也是生产环境最常用的搭配):

  • 前置准备:用rbenv或RVM在VPS上装好所有需要的Ruby版本,给每个Rails应用指定好对应版本(比如在应用目录下执行rbenv local 2.7.6),并完成bundle install和预编译(rails assets:precompile RAILS_ENV=production)。

  • 修改Nginx配置:找到你的域名配置文件(通常在/etc/nginx/sites-available/your-domain.conf),添加多个location块对应不同子路径:

server {
    listen 80;
    server_name example.com;

    # 第一个应用:Rails 6.1版本,对应子路径 /app1
    location /app1 {
        root /var/www/app1/public; # 应用的public目录路径
        passenger_enabled on;
        # 指定该应用用的Ruby版本(替换成你的rbenv/RVM路径)
        passenger_ruby /home/your-user/.rbenv/versions/2.7.6/bin/ruby;
        passenger_app_env production;
        # 关键配置:告诉Rails这个应用运行在子路径下
        passenger_base_uri /app1;
    }

    # 第二个应用:Rails 7.0版本,对应子路径 /app2
    location /app2 {
        root /var/www/app2/public;
        passenger_enabled on;
        passenger_ruby /home/your-user/.rbenv/versions/3.1.2/bin/ruby;
        passenger_app_env production;
        passenger_base_uri /app2;
    }

    # 可选:主应用(根路径 /)
    location / {
        root /var/www/main-app/public;
        passenger_enabled on;
        passenger_ruby /home/your-user/.rbenv/versions/3.0.4/bin/ruby;
        passenger_app_env production;
    }
}
  • 配置Rails子路径支持:每个子路径部署的应用,需要在config/environments/production.rb里添加前缀配置,避免静态资源404:
# 对应/app1的应用
config.action_controller.relative_url_root = "/app1"
  • 重启生效:执行sudo systemctl restart nginx,之后访问对应的子路径就能看到对应版本的应用了。

方案2:同域名下通过租户标识区分(多租户场景)

如果是多租户需求,希望同一个域名下不同租户访问不同版本的应用,可以通过请求头或URL参数来切换:

  • Nginx条件配置:在域名配置里根据请求头(比如X-Tenant-ID)动态指定应用目录和Ruby版本:
server {
    listen 80;
    server_name example.com;

    # 默认应用配置
    set $app_root /var/www/default-app/public;
    set $ruby_path /home/your-user/.rbenv/versions/3.0.4/bin/ruby;

    # 根据租户ID切换应用
    if ($http_x_tenant_id = "tenant1") {
        set $app_root /var/www/tenant1-app/public;
        set $ruby_path /home/your-user/.rbenv/versions/2.7.6/bin/ruby;
    }

    if ($http_x_tenant_id = "tenant2") {
        set $app_root /var/www/tenant2-app/public;
        set $ruby_path /home/your-user/.rbenv/versions/3.1.2/bin/ruby;
    }

    location / {
        root $app_root;
        passenger_enabled on;
        passenger_ruby $ruby_path;
        passenger_app_env production;
        # 把租户ID传给Rails应用,方便后续多租户逻辑处理
        passenger_env_var TENANT_ID $http_x_tenant_id;
    }
}
  • Rails多租户逻辑:在应用里通过ENV["TENANT_ID"]获取租户标识,实现数据库隔离、资源隔离等多租户功能。

关键注意事项

  • 版本隔离:一定要用rbenv/RVM给每个应用绑定独立的Ruby版本,Passenger的passenger_ruby参数必须指向对应版本的可执行文件,避免版本冲突。
  • 权限问题:确保Nginx运行用户(通常是www-data)对每个应用的public、tmp目录有读写权限,否则会出现500错误。
  • SSL适配:如果用HTTPS,只需要在server块里添加SSL证书配置即可,不影响多应用的部署逻辑。
  • 进程管理:Passenger会自动为每个应用维护独立的进程池,不用担心不同应用互相干扰。

内容的提问来源于stack exchange,提问作者S. Harper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:26:23