Answers · Deploying

How do I run a second Rails app on the same server?

Give the second app its own service name and its own host in config/deploy.yml. Kamal's proxy routes by hostname, so two apps share port 443 without conflict. What collides is anything pinned to a fixed host port, and the database volume path, which must differ or the two apps will share one SQLite file.

What has to be unique

Four things, and each one is a line in the second app's config/deploy.yml:

Setting Why
service Names the containers. A shared name means the second deploy replaces the first.
proxy.host How the proxy decides which app gets the request.
volume paths Two apps writing one SQLite file is data loss, not a conflict error.
any fixed host port Only one process can bind a port.
bin/kamal app containers
ssh your-server 'docker ps --format "table {{.Names}}\t{{.Ports}}"'

Run those before the second deploy. Anything already bound to 443 that is not Kamal's proxy is the thing that will break.

The volume line is the one that bites

Volumes are declared per app, and a copied config file keeps the source path of the app it was copied from:

volumes:
  - "second_app_storage:/rails/storage"

If both apps mount the same named volume, they open the same database file, and neither one reports a problem. You find out when rows from one app appear in the other.

Resources are shared, and nothing enforces a split

Two Rails apps on a 2GB VPS each run Puma workers and Solid Queue in the same container. A memory spike in one app causes the kernel to kill a process in either. If both apps matter, either size the box for the sum of both or accept that they share a failure.

bin/kamal app exec 'free -m' shows what is actually available, which is usually less than the plan says once the database and the proxy have their share.

When to use two servers instead

If the second app is a customer-facing service with its own uptime expectation, put it on its own host. The saving from co-tenancy is a few dollars a month, and the cost is that one deploy can take down two products. That trade is usually worth it for a side project and rarely worth it otherwise.

Related questions

How do I point a domain at a server running Kamal?

Create an A record for the apex pointing at the server's public IPv4 address, and a CNAME for www pointing at the apex. Set the same hostname in the proxy section of config/deploy.yml and redeploy. Kamal's proxy requests a certificate on the first request to that host, so HTTPS starts working within a minute of DNS resolving.

Can I run SQLite in production for a Rails app?

Yes, for one server. Rails 8 ships SQLite configured for production use, and One Shot runs on it: the database is a file on a mounted volume, backups are a file copy, and there is no second service to operate. The limit is real though. Two application servers cannot write to the same SQLite file, so horizontal scaling is where it stops.

How do I back up a SQLite database on a live server?

Run sqlite3 storage/production.sqlite3 ".backup /tmp/out.sqlite3" inside the container, then copy the result off the host. The .backup command takes a consistent snapshot while writes continue; a plain cp of a live database gives you a file that looks fine and fails on restore. Store it somewhere the server cannot reach.