Skip to main content
Multi-tenancy requires Spree Enterprise Edition license.
Spree can be configured to run a multi-tenant / SaaS platform. This guide will walk you through the steps to set up your Spree application to support multiple tenants (stores). Each tenant (store) can have its own isolated data and configuration, including:
  • customer accounts
  • staff accounts (admin users), staff can manage multiple tenants (it’s the standard invitation flow)
  • products, categories, and other catalog data
  • orders and order history
  • shipping and payment methods
  • tax rates and zones
  • store settings (name, logo, etc.)
  • etc.
All data is fully isolated besided the staff users, which can manage multiple tenants. This allows you to create a SaaS platform where each tenant can have its own store with its own branding and configuration. Isolation works across admin dashboard and API.
If you need individual seller/supplier/vendor accounts but shared product listings under one site you should use multi vendor recipe instead.

Prerequisites

  • You need to be on Spree 5.1+, we recommend using CLI to setup your Spree application.
  • You need to set 2 environment variables in your backend directory:
    • KEYGEN_ACCOUNT_ID
    • KEYGEN_LICENSE_KEY
  • Both PostgreSQL and MySQL are supported
You will need to add these environment variables to your CI/CD pipeline and staging/production environments.

Installing gems

  1. Add the following code to your Gemfile:
    source "https://license:#{ENV['KEYGEN_LICENSE_KEY']}@rubygems.pkg.keygen.sh/#{ENV['KEYGEN_ACCOUNT_ID']}" do
      gem 'spree_enterprise'
      gem 'spree_multi_tenant'
    end
    
  2. Install gems:
    spree bundle install
    
  3. Run generators:
    spree generate spree_enterprise:install && spree generate spree_multi_tenant:install
    
    This will copy and run migrations for spree_enterprise and spree_multi_tenant gems.

Setting root domain

Usually multi-tenant applications are configured to use subdomains for each tenant. For example, if your root domain is example.com, you can have tenants like tenant1.example.com, tenant2.example.com, etc. To make it work you need to set the Spree.root_domain in your config/initializers/spree.rb file, eg.
Spree.root_domain = 'example.com'
or use environment variable:
Spree.root_domain = ENV.fetch('SPREE_ROOT_DOMAIN', 'localhost')
This way you can also test it locally using localhost as root domain, and use tenant1.localhost, tenant2.localhost, etc. for tenants.

Customer User Class adjustment

We need to make slight adjustments to the user class so it can work in a multi-tenant environment. You need to remove :validatable module. This module is responsible for validating the user’s email uniqueness. We need to change it to validate it in the scope of the tenant.
backend/app/models/spree/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable, :validatable
  devise :database_authenticatable, :registerable, 
         :recoverable, :rememberable, :trackable, :confirmable

  include SpreeMultiTenant::CustomerUserConcern
end