Skip to main content
This guide walks you through deploying PostgreSQL to Magic Containers, either as a standalone container or as part of a multi-container app alongside your application. You’ll need a bunny.net account with Magic Containers enabled.

Quickstart

1

Create a new app

Go to the bunny.net dashboard, select Magic Containers, and click Add App. Select Single region deployment.
Databases should use single region deployment with a single instance. Each pod gets its own dedicated volume with no data replication — this applies both across regions and within the same region. Scaling to multiple pods or regions would result in separate, isolated databases each with their own data.
2

Add the PostgreSQL container

Click Add Container and configure the image:
  • Registry: Docker Hub
  • Image: library/postgres
  • Tag: 17-alpine
Magic Containers will automatically detect the required endpoint and environment variables for the image. Configure the environment variables as needed:
  • POSTGRES_USER = postgres
  • POSTGRES_PASSWORD = a strong password
  • POSTGRES_DB = app
  • PGDATA = /var/lib/postgresql/data/pgdata
3

Add a persistent volume

In the Volumes section of the container settings, add a volume:
  • Name: postgres-data
  • Mount path: /var/lib/postgresql/data
This ensures your database files persist across restarts and redeployments. Without a volume, all data is lost when the container stops.See persistent volumes for more details on volume behavior and pricing.
4

Deploy

Review your settings and click Confirm and Create.
Always set a strong POSTGRES_PASSWORD, even if the database is not exposed externally. Other containers in the same pod can access the network, and a password protects against accidental or unauthorized access.
You must set PGDATA to a subdirectory of the volume mount (e.g. /var/lib/postgresql/data/pgdata). PostgreSQL requires the data directory to be empty on first initialization, and the volume mount point itself may contain system files.

Environment variables

The official PostgreSQL image supports these environment variables:
VariableDescriptionDefault
POSTGRES_USERSuperuser namepostgres
POSTGRES_PASSWORDSuperuser password (required)-
POSTGRES_DBDefault database created on first startpostgres
PGDATAData directory inside the container/var/lib/postgresql/data

Connect from your app

In a multi-container setup, your app and PostgreSQL share the same localhost network. Connect using 127.0.0.1 and the default port 5432.
postgresql://postgres:YOUR_PASSWORD@127.0.0.1:5432/app

Multi-container example

A typical setup pairs PostgreSQL with your application. When configuring the app, add two containers:

App container

  • Image: your app image (e.g. ghcr.io/<your-username>/my-app:latest)
  • Endpoint: the port your app listens on
  • Environment variables:
    • DATABASE_URL = postgresql://postgres:YOUR_PASSWORD@127.0.0.1:5432/app

PostgreSQL container

  • Image: postgres:17-alpine
  • Volume: mount path /var/lib/postgresql/data
  • Environment variables:
    • POSTGRES_USER = postgres
    • POSTGRES_PASSWORD = a strong password
    • POSTGRES_DB = app
    • PGDATA = /var/lib/postgresql/data/pgdata
Both containers share the same localhost network, so your app connects to PostgreSQL at 127.0.0.1:5432. See multi-container apps for more details.

External access

To connect to PostgreSQL from outside Magic Containers (e.g. from your local terminal), add an Anycast endpoint:
  1. Go to your app’s Endpoints tab and click Add New Endpoint
  2. Select Anycast as the type
  3. Set Container Port to 5432
  4. Set Exposed Port to 5432
  5. Click Add Endpoint
Then connect using the Anycast IP and the exposed port:
psql -h <anycast-ip> -p <exposed-port> -U postgres -d app
The exposed port and container port may differ. When connecting externally, always use the exposed port shown in your endpoint configuration.
Exposing your database to the internet means anyone with the credentials can connect. Use a strong password and consider removing the Anycast endpoint when external access is no longer needed.