Mastering Multi Tenant setup with rails part 1
Multi-tenancy is a software design where a single instance of a software application serves multiple customers or tenants (individual users or organizations). In a multi-tenant architecture, each tenant’s data and configuration are logically isolated from one another, providing a sense of individuality and privacy while sharing the same underlying infrastructure, codebase, and application instance.
Single Tenant application
In a single-tenant application, each hosted instance has its dedicated database. Upon addition of a new organization that requires segregated data, a new application is hosted with a different database.
Multi Tenant Application types
- Single Database shared rows
- Each table in database will contain an additional row known as tenant_id.
- Whenever data is stored and retrieved from table this coloumn will be used to get/store the data.
-
Only the data that belongs to a specific customer/tenant will be fetched.
- Single Database shared schema
- For each tenant a different table will be maintained in same database.
-
Data will be segregated table wise.
- Dedicated Database for Each Tenant
-
For each tenant a new database schema will be maintained, it can be termed as shard.
-
In this blog post, we’ll take an in-depth look at the third approach, where we opt to manage separate databases for each tenant. To demonstrate this, we’ll walk through the process of creating a basic Rails blog application from the ground up.
Goal
- Setting up a multi-tenant application in development mode.
- dynamically switching databases according to the requesting host name.
What features rails 6 brings in
Rails 6 introduced the multiple database setup with following features -
- Multiple writer databases and a replica for each.
- Automatic connection switching for the model you’re working with.
- Automatic swapping between the writer and replica depending on the HTTP verb and recent writes.
- Rails tasks for creating, dropping, migrating, and interacting with the multiple databases.
Setup
Create new rails app
rails new multi_db_blog
- update gemfile to use mysql2 instead of sqlite3
Setup databases
- In
database.yml
file update the database with name.
bin/rake db:create
create databases for both the tenants.- You have the option to execute specific rake commands for each database. For instance, you can create the
app1
database using the command:bin/rake db:create:app1
Generate Models and Controller
-
Model
bin/rails generate model Article title:string body:text
-
Run migrations
bin/rake db:migrate
-
Controller
bin/rails generate controller Articles index --skip-routes
-
update
routes.rb
file.
Complete the Articles
Controller, Model and respective views by following This Guide
Start App
- Run
bin/rails s
to start the server. - By default rails will connect to db1 now.
- This will act as a default database for the current application.
Running up both databases simaltaneously
Install nginx & paste the following code in nginx.conf file.
Above nginx configurations listens to port 3000 and 4000 and redirect to rails application running in port 3000.
Additional Rails changes
Since We are using Rails 7 we can use automatic shard swap feature provided by rails. if using rails 6.1 or 6, a middleware can be introduced to automatic switch the tenants depending on request. Visit next section for the details.
Mention list of tenants in a .yml
file. You can maintain these records in a separate database as well, for now I will create a settings.yml
file.
update application.rb
with following configurations.
update application_record.rb
Creating Middleware for automatic shard switching(ignore if using rails 7 or above)
- Create a middleware named
middleware/tenant_selector.rb
- Add following code
- Update
application.rb
file with following changes.
Final Steps
Follow these final steps to confirm your multi-tenant Rails application is up and running smoothly:
- Run
bin/rails s
- Access localhost:3000 to connect to db1
- Access localhost:4000 to connect to db2
- If you wish to add more databases, simply update the
database.yml
andsettings.yml
files
What Next?
In the upcoming series of blog posts, we will delve into the following topics:
- Maintaining Background Jobs.
- Running Rake Tasks with Cron Jobs for Multiple Databases.
- ActiveStorage Data Management with Different Storage Types for Each Tenant.
- Caching.
Summary
In this blog post we covered creating a multi tenant application from scratch and setting it up in development environment. We were able to automatically switch databases according to type of database.