Run Postgres
Last updated
Postgres runs well as its own application. Read Databases first if you haven't — the important context is that its port will be publicly reachable, because there is no private networking.
Create the database app
Use Existing Image, which lets you set everything at creation time.
- Image:
postgres:16(or your preferred version — pin it, don't uselatest) - Volume:
/var/lib/postgresql/data - Port: container
5432, protocol TCP - Environment variables:
POSTGRES_PASSWORD— a long random valuePOSTGRES_USER— optional, defaults topostgresPOSTGRES_DB— optional, the database created on first start
The volume is not optional. Without it, your entire database is discarded the next time the container is recreated — which happens on any configuration change, not just a deploy.
Note the address
A TCP binding is published on a platform host with a generated high port number, not 5432. Take the host and port from the app's Ports tab; that pair is your connection address.
Connect your application
Set a connection string as an environment variable on the application, not the database:
DATABASE_URL=postgres://USER:PASSWORD@HOST:PORT/DBNAME
Nothing injects this for you. Create the database app first, read its address, then set the variable — that ordering is the whole setup.
Secure it, because it's public
- A long random password, generated rather than chosen. This is the only thing between your data and the internet.
- Remove the port binding when you don't need it. If only your own app connects, and you're not using a local client, unbind it.
- Enable TLS if your client supports it.
- Keep a small connection pool. Five is plenty for a small app; a default of twenty from a fractional-CPU container is optimistic and costs the database memory.
Migrations
Run them deliberately, not from your app's start command. Startup code runs on every container start — every deploy, every config change, and every iteration of a crash loop — which is a bad place to be applying schema changes.
Use the app's shell for one-off migrations, or gate them behind a variable you set for a single deploy.
Backups
Nothing backs this up for you.
pg_dump -h HOST -p PORT -U USER DBNAME > /data/backup.sql
Write dumps to a volume, then download them from the Files tab, or ship them off-platform on a schedule. Prune old ones — volume size counts toward the account disk limit that stops all your apps when exceeded.
Sizing
Postgres is comfortable on a small allocation for a small workload, but it does have a floor — it isn't a bottom-preset service alongside your app. Start modest and raise it on evidence.