Services About Us Why Choose Us Our Team Development Workflow Technology Stack Case Studies Portfolio Blog Free Guides Shopify Audit ($499) Estimate Project Contact Us
Back to Insights
Ruby on Rails • Oct 03, 2026 • 5 min read

Building Multi-Tenant SaaS on Rails 8: Kamal 2, SSL & Custom Domains

Building a multi-tenant SaaS on Rails 8 in late 2026 requires leveraging Kamal 2, dynamic wildcard routing, and automated Let's Encrypt SSL provisioning via Kamal-proxy. This modern stack eliminates expensive PaaS pla...

TV
TechVinta Team
Specialized in Rails, React, Marketplace & Sharetribe Flex Architecture
Verified Technical Guide
Building Multi-Tenant SaaS on Rails 8: Kamal 2, SSL & Custom Domains

Direct Answer: Building Multi-Tenant SaaS on Rails 8

Building a multi-tenant SaaS on Rails 8 in late 2026 requires leveraging Kamal 2, dynamic wildcard routing, and automated Let's Encrypt SSL provisioning via Kamal-proxy. This modern stack eliminates expensive PaaS platforms like Heroku, enabling scalable database-per-tenant or schema-based isolation directly on bare-metal or cloud VMs for a fraction of the cost.

Architectural Foundations of Multi-Tenancy in Rails 8

Multi-tenancy architectures generally fall into three patterns: database-per-tenant, schema-per-tenant, and row-level security (pooled). For enterprise B2B SaaS, the database-per-tenant approach provides the ultimate security and data isolation guarantees, while schema-per-tenant strikes an optimal balance between resource utilization and operational complexity.

In Rails 8, multi-tenancy is natively supported through connection management extensions and the robust Active Record connection switching API. Let's look at how we configure a dynamic tenant switcher using middleware to intercept requests, extract the subdomain, and route database connections securely.


# app/middleware/tenant_elevator.rb
class TenantElevator
  def initialize(app)
    @app = app
  end

  def call(env)
    request = Rack::Request.new(env)
    subdomain = extract_subdomain(request.host)

    if subdomain.present? && subdomain != "www"
      tenant = Tenant.find_by!(subdomain: subdomain)
      
      Current.tenant = tenant
      ActsAsTenant.with_tenant(tenant) do
        @app.call(env)
      end
    else
      @app.call(env)
    end
  rescue ActiveRecord::RecordNotFound
    [404, { "Content-Type" => "text/plain" }, ["Tenant not found"]]
  end

  private

  def extract_subdomain(host)
    parts = host.split(".")
    # Assumes app.com is 2 parts, tenant.app.com is 3 parts
    parts.size > 2 ? parts.first : nil
  end
end

To register this middleware in your Rails 8 application, update your config/application.rb file:


# config/application.rb
module TechVintaSaaS
  class Application < Rails::Application
    config.load_defaults 8.0
    config.middleware.use TenantElevator
  end
end

Automated Deployment with Kamal 2 and Kamal-Proxy

Kamal 2 revolutionized zero-downtime deployments by introducing advanced proxy capabilities, native multi-accessory support, and built-in Let's Encrypt SSL provisioning via kamal-proxy. Unlike traditional reverse proxies (Nginx/Caddy) that require manual certificate management, Kamal 2 automates TLS handshakes and wildcard domain validation at the edge.

Below is a production-grade config/deploy.yml optimized for a multi-tenant Rails 8 application managing dynamic custom domains:


# config/deploy.yml
service: techvinta-saas
image: registry.digitalocean.com/techvinta/saas-core

servers:
  web:
    hosts:
      - 165.232.32.10
    options:
      ports:
        - "443:443"
        - "80:80"

proxy:
  ssl: true
  host: app.techvinta.com
  proxy_args: "--tls-calets"
  healthcheck:
    path: /up
    interval: 2
    timeout: 3

registry:
  server: registry.digitalocean.com
  username: 
    - KAMAL_REGISTRY_USERNAME
  password: 
    - KAMAL_REGISTRY_PASSWORD

env:
  clear:
    DB_HOST: 165.232.32.11
    RAILS_MAX_THREADS: 5
  secret:
    - RAILS_MASTER_KEY
    - DATABASE_URL

Handling Wildcard and Custom Domains at Scale

Enterprise SaaS clients demand custom domain mapping (e.g., app.clientcompany.com). Achieving this with Kamal 2 requires dynamic proxy configuration updates without triggering full container restarts. Kamal-proxy exposes an internal API that allows your Rails application to programmatically bind new domains and trigger SSL certificate generation via ACME protocols.

When a tenant updates their custom domain in your Rails admin panel, invoke a background job to register the domain with the proxy daemon:


# app/jobs/provision_custom_domain_job.rb
class ProvisionCustomDomainJob < ApplicationJob
  queue_as :default

  def perform(tenant_id)
    tenant = Tenant.find(tenant_id)
    domain = tenant.custom_domain

    # Interact with Kamal-proxy API or local socket
    uri = URI("http://localhost:3000/proxy/domains")
    http = Net::HTTP.new(uri.host, uri.port)
    request = Net::HTTP::Post.new(uri.path, { 'Content-Type' => 'application/json' })
    request.body = { domain: domain, backend: "http://web:3000" }.to_json

    response = http.request(request)
    unless response.is_a?(Net::HTTPSuccess)
      raise "Failed to provision SSL for #{domain}: #{response.body}"
    end
  end
end

2026 Architecture & Cost Comparison

Choosing the right stack impacts your engineering overhead, hosting bills, and time-to-market. The matrix below contrasts a modern Rails 8 + Kamal 2 architecture against legacy PaaS and alternative frameworks.

Metric / Feature Rails 8 + Kamal 2 (Bare Metal/Cloud) Legacy Heroku / Render PaaS Custom Node.js / Kubernetes No-Code / Sharetribe ($8k-$25k)
Infrastructure Cost (Monthly) $40 - $120 (Scales with RAM) $300 - $1,200+ (Add-on heavy) $500 - $2,000+ (DevOps overhead) $199 - $500/mo subscription
SSL & Wildcard Automation Native via Kamal-proxy & Let's Encrypt Managed (Expensive tier upgrades) Requires cert-manager / Traefik Platform restricted
Engineering Hourly Rate $35 - $65/hr (TechVinta Tier) $35 - $65/hr $90 - $150/hr (K8s specialists) N/A (Restricted customization)
Data Isolation Security Strict Schema / DB per tenant Application-level filtering (Row security) Configurable Kubernetes Namespaces Shared multi-tenant database
Deployment Speed < 90 seconds (Docker push & swap) 2 - 5 minutes (Git push) 10 - 20 minutes (CI/CD pipeline) Instant visual builder

Accelerate Your SaaS Delivery with TechVinta

Architecting a production-ready, multi-tenant SaaS application with custom domain routing and automated SSL demands deep DevOps and Rails expertise. At TechVinta, our elite engineering team specializes in scaling modern Ruby on Rails applications using Kamal 2, Docker, and cutting-edge cloud infrastructure. We operate with a seamless 4 to 6-hour US timezone overlap, ensuring real-time collaboration, rapid code reviews, and agile sprint execution for North American startups and scale-ups. Contact TechVinta today to accelerate your product roadmap.

Frequently Asked Questions

How does Kamal 2 handle SSL certificate renewal for hundreds of tenant custom domains?

Kamal 2 integrates directly with Let's Encrypt ACMEv2 challenges through kamal-proxy. When a custom domain is registered, the proxy daemon automatically requests, stores, and handles background certificate renewal cycles prior to expiration, eliminating manual certificate maintenance.

Is a database-per-tenant strategy better than row-level security in Rails 8?

Database-per-tenant offers absolute data isolation and simplifies regulatory compliance (GDPR/HIPAA), whereas row-level security (using gems like acts_as_tenant) is more cost-effective for high-density, low-tier SaaS products. Rails 8 natively supports connection switching, making database-per-tenant orchestration much cleaner than in previous versions.

How does TechVinta ensure zero-downtime deployments during schema migrations?

We implement robust backward-compatible database migration patterns (expand-and-contract pattern) combined with Kamal 2's rolling container swaps. This ensures that ongoing tenant requests never fail or timeout while database schemas are updated in production.

⚡ Interactive Sizing Tool

Ruby on Rails 8 Upgrade Sizing & Cost Estimator

Estimate upgrade sprints, budget ranges at our senior US-aligned rate ($45/hr), and annual infrastructure savings with Solid Queue & Kamal 2.

Estimated Timeline
4–6 Weeks
2–3 Agile Sprints
Budget ($45/hr)
$7,200 – $11,500
Fixed-Price Milestones
Annual Cloud & Redis Savings: $4,800 / year
Dropping Redis for Solid Queue + migrating from Heroku to Kamal 2 on Hetzner/AWS bare-metal saves 60–80% monthly hosting overhead.
Zero-Downtime Guarantee: Dual-boot Gemfile strategy ensures your current Rails production app continues shipping features while Rails 8 branch is perfected.
Senior Rails & Sharetribe Architecture

Building, Scaling, or Modernizing Your Platform?

TechVinta delivers senior engineering ($35–$65/hr) with guaranteed 4–6 hours daily US EST/PST overlap. We specialize in custom Sharetribe Flex marketplaces, Ruby on Rails 8 modernizations, and high-throughput Stripe Connect integrations.

⚡
$35–$65/hr Transparent RatesDirect senior talent, no agency bloat
🇺🇸
4–6h Daily US OverlapLive EST/PST syncs & sprint reviews
🔒
100% Client IP & NDAEnterprise standards & clean code
Book a 15-Min Intro Call Get Free Project Sizing →
Share this article:
TV

Written by TechVinta Team

We are a full-stack development agency specializing in Ruby on Rails, React.js, Vue.js, Flutter, Shopify, and Sharetribe. We write about web development, DevOps, and building scalable applications.

Need Senior Developers?
$35–$65/hr · 4–6h US overlap

Keep Reading

TechVinta Assistant

Online - Ready to help

Hi there!

Need help with your project? We're online and ready to assist.

🍪

We use cookies for analytics to improve your experience. See our Cookie Policy.