Kamal Rails on AWS Series Part 2: Add AWS RDS to your Rails application

In Part 1 of this Kamal series, we deployed a vanilla Rails application to a remote server using Kamal. By default, Rails applications use SQLite, but most production applications require Postgres. This article shows how to configure Postgres and deploy it using Kamal with AWS RDS as a managed database service.

This article assumes you have a Rails application backed by Postgres running locally. If you use a different database like MySQL, you can adapt these instructions accordingly. If you’re using SQLite, you can skip this article.

There are two approaches to deploying Postgres with a Rails application:

  • On the same VM as your application (less common)
  • Using a managed database service like AWS RDS (more common)

We’ll use AWS RDS for this guide.

Step 1: Create an RDS Instance in AWS

  • Log in to AWS
  • Navigate to RDS and click “Create database”
  • Select “PostgreSQL” as the database engine
  • Choose your preferred Postgres instance size and keep other settings at their defaults
  • When prompted to connect with an EC2 instance, select yes
  • Choose the EC2 instance you created in Part 1
    • AWS automatically creates a security group allowing your EC2 instance to connect to RDS
    • After creating the RDS instance, verify connectivity from your EC2 instance:
      1
      
      psql "host=YOUR_RDS_ENDPOINT port=5432 dbname=postgres user=MASTER_USER password=MASTER_PASSWORD sslmode=require"
      
    • Find RDS details in AWS Console → RDS → Databases → your DB → Configuration
    • You may need to check AWS Secrets Manager for the username and password
    • Install psql on your EC2 instance if needed: sudo apt-get install postgresql-client

Step 2: Configure Your database.yml to Use Environment Variables

  • Update your database.yml to read the database URL from environment variables:
1
2
3
production:
  <<: *default
  url: <%= ENV["DATABASE_URL"] %>
  • If you’re using PostGIS and need to replace postgres:// with postgis://, use:
1
2
3
production:
  <<: *default
  url: <%= ENV["DATABASE_URL"].gsub("postgres://", "postgis://") %>
  • If you encounter parsing errors due to special characters in the password (like @ or :), split the URL into individual components:
1
2
3
4
5
6
7
8
production:
  <<: *default
  host: <%= ENV["DB_HOST"] %>
  username: <%= ENV["DB_USER"] %>
  database: <%= ENV["DB_NAME"] %>
  password: <%= ENV["DB_PASSWORD"] %>
  adapter: postgis
  sslmode: require
  • Set the database name to kamal_app_demo_production

Step 3: Configure Environment Variables in deploy.yml

  • Add the following to your config/deploy.yml file:
1
2
3
4
5
6
7
8
9
env:
  clear:
    PORT: 3000
  secret:
    - RAILS_MASTER_KEY
    - DB_HOST
    - DB_NAME
    - DB_USER
    - DB_PASSWORD
  • Add these keys to your .kamal/secrets file:
1
2
3
4
5
6
7
# .kamal/secrets
secrets:
  RAILS_MASTER_KEY: $RAILS_MASTER_KEY
  DB_HOST: $DB_HOST
  DB_NAME: $DB_NAME
  DB_USER: $DB_USER
  DB_PASSWORD: $DB_PASSWORD
  • Store actual credentials in your .env file:
1
2
3
4
5
6
7
# .env file

RAILS_MASTER_KEY=<our_rails_production_master_key>
DB_HOST=<our_rds_endpoint>
DB_NAME=<our_rds_db_name>
DB_USER=<our_rds_username>
DB_PASSWORD=<our_rds_password>

Step 4: Deploy Your Application

After completing the configuration above, deploy your Rails application with RDS:

1
kamal deploy

Your Rails application should now be running with RDS as the database.

For commonly used Kamal commands, see this article.

Next Steps

You’ve now completed the AWS series with a Rails application deployed on AWS with RDS. For additional Kamal configuration topics, check out:

Previous articles in this AWS series:

NOTE:

  • If this article is out of date, please don’t hesitate to contact me on Twitter from this page and I’ll be happy to update it.
  • Listen to this podcast where DHH talks about Rails and Kamal.
  • If you would like to search for specific terms or concepts or names in Ruby/Rails podcasts, check out rubypodcatcher.com
This post is licensed under CC BY 4.0 by the author.