Deploying a Rails App with Postgres
To deploy a Rails app with Postgres to a server you have ssh access to using Kamal, start with what the Rails app needs to connect to the db: POSTGRES_USER POSTGRES_PASSWORD DB_HOST POSTGRES_DB. These env vars are used in config/database.yml like this:
production:
primary: &primary_production
<<: *default
username: <%= ENV['POSTGRES_USER'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
host: <%= ENV['DB_HOST'] %>
port: <%= ENV.fetch('DB_PORT', 5432) %>
database: <%= ENV['POSTGRES_DB'] %>
The POSTGRES_ env vars are named that way for the postgres docker image.
Add the accessory
In the accessories section of config/deploy.yml, add a postgres database:
accessories:
db:
image: postgres:18.3
host: <server ip>
env:
clear:
POSTGRES_DB: my_app_production
POSTGRES_USER: my_app
secret:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql
Here, the env vars control how the postgres image is configured. Check the official postgres docker image docs for more info. The value of POSTGRES_PASSWORD comes from .kamal/secrets.
App container env
With the db accessory configured, give the app container the env vars it needs:
service: my_app
# ...
env:
secret:
- POSTGRES_PASSWORD
clear:
POSTGRES_USER: my_app
DB_HOST: my_app-db
POSTGRES_DB: my_app_production
POSTGRES_PASSWORD comes from the same secret that the db accessory has. POSTGRES_USER and POSTGRES_DB are also copied over. DB_HOST is a value that comes from Kamal. By default, it’s the combination of the service name and the postgres accessory key separated by a dash(docker container network).
With that, boot the db accessory then deploy the application.