Deploying App + Database Separately
When a project includes stateful dependencies (databases, caches, queues), deploy them as their own Exoframe services. That way, you can redeploy your app without restarting the database, and version each component independently.
1. Create a database deployment
-
Add a config file for the database, e.g.
infra/postgres.json:infra/postgres.json{
"name": "prod-postgres",
"domain": false,
"image": "postgres:15",
"hostname": "prod-postgres",
"volumes": ["prod_pg_data:/var/lib/postgresql/data"],
"env": {
"POSTGRES_PASSWORD": "@pg-password"
},
"restart": "unless-stopped"
} -
Deploy it once:
exoframe deploy -c infra/postgres.json.
The database now runs as a long-lived container without any app code bundled in.
2. Describe the application deployment
Create exoframe.json for the app itself:
exoframe.json
{
"name": "prod-app",
"domain": "app.example.com",
"env": {
"DATABASE_URL": "postgres://postgres:@prod-postgres:5432/appdb"
},
"project": "app-prod",
"restart": "on-failure:3"
}
- The
DATABASE_URLuses the database container’s hostname (prod-postgres) so traffic stays on the internal Docker network. - Keep any other infra services (Redis, RabbitMQ, etc.) described in their own configs the same way as the database example.
3. Deploy and iterate independently
- Deploy the application:
exoframe deploy. - Verify both services are healthy:
exoframe ls. - When you need to roll out app changes, redeploy only the app; the database keeps running unharmed.
- Only redeploy the database config when changing the image version or environment.
This pattern keeps deployments faster, avoids unnecessary downtime for stateful services, and mirrors how Exoframe v7 is designed to manage multi-container systems.