The multitenancy feature allows managing several independent institutions ("tenants") using the same application. For example, in our case, a user who signs up for a certain tenant will only be able to sign in on that tenant, and that user's data won't be available from any other tenant.
Which tenant we're accessing depends on the URL we're using in the browser to access the application. In CONSUL, the current tenant is established by the subdomain used in this URL. For example, if we used the domain
solarsystemexample.orgto manage the planets in the Solar System, using the URL
https://mercury.solarsystemexample.orgwe'd access data from the planet Mercury while using the URL
https://venus.solarsystemexample.orgwe'd access data from the planet Venus. It's also be possible to use different domains per tenant (for example,
If you're upgrading a CONSUL installation to version 2.0.0 from version 1.5.0, you'll have to follow these steps before enabling multitenancy. These steps aren't necessary on new CONSUL installations.
First, after deploying version 2.0.0 to your production server, execute the release tasks:
RAILS_ENV=production bin/rails consul:execute_release_tasks
After runing this command, you might get the following warning:
The database search path has been updated. Restart the application to apply the changes.
If that's the case, restart the application. If not, make sure the
config/database.ymlfile contains the line
schema_search_path: "public,shared_extensions"and, if that's not the case, add it for example below the line saying
adapter: postgresqland restart the application.
Next, open a database console with a user having permission to create and manage database extensions:
sudo -u postgres psql -d consul_production
If you didn't use the installer to install CONSUL, you might need to execute a couple of queries to make sure the Rails database user has permission to create schemas and the shared extensions schema has the right permissions:
CREATE SCHEMA shared_extensions AUTHORIZATION <replace_with_rails_database_username>;
GRANT CREATE ON DATABASE consul_production TO <replace_with_rails_database_username>;
GRANT usage ON SCHEMA shared_extensions TO public;
Whether or not you installed CONSUL with the installer, run:
ALTER EXTENSION pg_trgm SET SCHEMA shared_extensions;
ALTER EXTENSION unaccent SET SCHEMA shared_extensions;
There are two possible ways to enable multitenancy:
config.multitenancy = trueinside the
class Application < Rails::Applicationclass in the
- Replacing the line
multitenancy: true(or adding it if it isn't already there) in the
The difference between these options is that the first one uses a file under version control while the second one uses a file which isn't under version control. Choose the first option if you'd like to have this change in your git repository; otherwise, use the second one.
After enabling this option, restart the application.
Once multitenancy has been enabled and the application has been restarted, you'll see a new "Multitenancy" section inside the "Settings" menu in the CONSUL admin panel.
New section with the list of tenants, with their name and domain or subdomain
This section will only be available from the "main" tenant (the one which is created by default). It will not be possible to add/edit tenants by accessing the admin section of any other tenant.
Since removing a tenant would delete all its associated data, making it impossible to restore it, CONSUL doesn't allow deleting a tenant using the admin panel. However, it's possible to disable a tenant so it cannot be accessed.
The interface to manage tenants is very simple, needing just a name and a domain or subdomain.
Form to edit a tenant, with name and domain or subdomain fields; radio buttons are used to choose domain or subdomain
The name will be used to set the default site name for new tenants. Note that, once a tenant is created, changing this name will have no effect. To change the site name of an existing tenant, edit it in the "Global settings" section in the administration of that tenant.
The domain or subdomain will be used to access this tenant. If you've got a domain like
solarsystemexample.organd would like to access tenants using subdomains (like
mars.solarsystemexample.org), choose "Use a subdomain". If you're using a different domain for the tenant (like
marsexample.org), choose "Use a different domain".
Note that, if you use a different domain for a tenant, you'll have to configure your SSL certificates, web server and DNS so they support that domain and point to your CONSUL application.
When adding a new tenant, an admin user copying the same login data as the administrator creating the tenant will be automatically created. Note this user is stored in the database schema of the new tenant, so changing their password in one tenant won't change their password in any other tenants.
In order to make it possible to access the application using secure HTTPS/SSL connections, you'll need a valid SSL certificate for the tenant you've just added. Since every institution using CONSUL has a different system to manage these certificates, getting a valid SSL certificate for the new tenant will need a different process depending on the way your institution manages these certificates.
If you've installed CONSUL using the installer and are using Certbot to manage these certificates, you have two options.
One option would be adding each certificate manually every time you create a tenant. For example, in orer to add a tenant using the
marssubdomain in the
sudo certbot certonly --nginx --noninteractive --agree-tos --expand -d solarsystemexample.org,mars.solarsystemexample.org
If you're going to add many subdomains at different times, this task can be tedious. Another option is enabling any subdomain. In order to achieve this goal, you need access to your DNS configuration in order to follow the instructions you'll get by either using one of the Certbot DNS plugins or the manual generation of the certificate with the following command:
sudo certbot certonly --manual --agree-tos --expand -d solarsystemexample.org,*.solarsystemexample.org
You'll be asked to create a DNS TXT record with the subdomain
_acme-challengeon your domain, with a certain value. You might also be asked to create a file with a certain name containing a certain content (usually in a
.well-known/acme-challengefolder); if that's the case, assuming you're using CONSUL's default folders, create it in
After doing so, update your web server configuration file (by default
/etc/nginx/sites-enabled/default) so it uses the generated certificate, and restart the web server with
sudo systemctl restart nginx.
In order to reduce the chance your application sends emails which are erronously identified as spam, you might want to edit the fields "Sender email name" and "Sender email address" in the administration panel of the new tenant. The default values for these fields are the name and subdomain introduced when creating the tenant.
Fields to edit sender email name and address
If you'd like to use a different mail configuration for the new tenant, like one for a hypothetical
jupitersubdomain, edit the
config/secrets.ymlfile this way:
# (...) Other secrets
# (...) Other secrets
After editing this file, restart the application.
If you've configured applications so users can sign in via Twitter, Google, Facebook or Wordpress, you need to allow the new tenant to access these applications. You have two options.
The first option is changing your existing application using the Twitter/Google/Facebook/Wordpress dashboard and add the new tenant's URL to the list of allowed domains. When doing so, take into account your application's terms and conditions settings, which might not be compatible with this option.
The other option is creating a new Twitter/Google/Facebook/Wordpress application and configuring it so it can be used from the new tenant. In this case, you'll have to add the configuration of this application to the
config/secrets.ymlfile. For example, if you've added a tenant using the
saturnsubdomain, edit the file this way, filling in the keys and secrets of the services you're using:
# (...) Other secrets
# (...) Other secrets
After editing this file, restart the application.
When CONSUL creates a tenant, it loads the content of the
db/schema.rbfile to create a new database schema for the new tenant. This means that if for some reason this file doesn't contain the same database structure you'd get by creating a new database and running the migrations with
rake db:migrate, you could end up with different database table or columns on different tenants. This could result in a disastrous situation.
In order to avoid it, we recommend checking the integrity of the
db/schema.rbfile in your continuous integration system. If you're doing continuous intergration using GitHub Actions, you can use the workflow already included in CONSUL. Pull requests adding this check on GitLab CI or other continuous intergration environments are welcome.
When the multitenancy feature is enabled, CONSUL adds a class to the
uranussubdomain would have the
This way, it'll be possible to overwrite the default styles for just this tenant by creating a new stylesheet in the
// Styles that will only be applied to the Uranus tenant
To easily change the default colors on a specific tenant, you can use CSS variables; their usage is documented in the app/assets/stylesheets/custom/tenants.scss file. For example, to make the brand colors green on the tenant with the
Sometimes it might be convenient to use completely different views for different tenants. For example, a certain tenant might use a footer that has nothing to do with the default one.
In these cases, instead of adding conditions like
case Tenant.current_schemato the view, using a different file might result in code easier to maintain.
For this purpose, we can use Rails variants, which means that, for example, a tenant named
milky-waywill use a view file ending with
.html+milky-way.erbif it's available. That is, in order to use a different
application.html.erblayout for the
milky-waytenant, add a new file under
We recommend only using this feature when there are substantial differences between the default view and the specific view for a tenant. If the differences are small, use
caseconditions instead in order to avoid code duplication.
The same principle works for components too, but in this case, when using the
custom/folder to add ERB files for a tenant, the default tenant ERB file needs to be added to the
custom/folder as well; if there aren't changes to this file, a symbolic link will do.
For example, if you're writing a custom
admin/action_componentcomponent view for the
milky-waytenant but don't need to change this file for the default tenant:
- 1.Create the
app/components/custom/admin/action_component.rbfile according to the components customization documentation
- 2.Create the custom view for the
milky-waytenant and save it under
- 3.Enter the
app/components/custom/admin/folder and run
ln -s ../../admin/action_component.html.erb
The multitenancy feature was first included in CONSUL 2.0.0 and there are a few things that are still missing.
You might have a CONSUL application which can be accessed from two different domains; for example,
solarsystemexample.organd a domain in Spanish named
In this case, the source code needs to be changed a little so multitenancy works with both domains. In particular, the
allowed_domainsmethod in the
Tenantclass needs to be changed in order to include both domains. See the models customization documentation for examples on how to customize methods like this one.
The administration panel in CONSUL contains a "Custom images" section, where you can customize some (but not all) images appearing in the application. Using this interface allows having different images per tenant.
Sometimes it's useful to have a certain image under version control, though. For instance, if we'd like to use a different logo for a tenant with the
neptunesubdomain, we'd put that file under
However, this will only work for images which can already be configured through the administration interface. If you'd like to customize a different image, you'll have to change the code rendering it. For instance, to make it possible to customize the
avatar_admin.pngimage, replace the code
In CONSUL 2.0.0, data from all tenants is stored in the same database and so it isn't possible to use several databases on different servers.
If this feature is requested often, it'll be possible to include it in CONSUL in the future. However, CONSUL 2.0.0 uses Rails 6.0 and this feature will require upgrading to Rails 6.1 or even Rails 7.0.
In CONSUL 2.0.0, every tenant is available in the same languages, so it wouldn't be possible (for instance) to enable French in one tenant and German in a different one; you'd have to enable both languages in both tenants.
Implementing this feature is planned for CONSUL 2.1.0.
Since removing a tenant would delete all its associated data, making it impossible to restore it, CONSUL doesn't allow deleting tenants using the admin panel and only allows disabling them so they cannot be accessed. To completely delete a tenant, use the Rails console.