This guide walks you through converting your existing vibe-dev application from using the shared postgres database to running your own dedicated PostgreSQL container as part of a self-contained stack.
Why migrate?
The shared postgres instance on vibe-dev was intended as a convenience for early development. Moving to a dedicated database per application gives you:
- Isolation — your database lives and dies with your app, no cross-app dependencies
- Portability — your entire app is defined in one
docker-compose.yml - Safety — schema changes, migrations, and credential rotation don't affect other apps
- Easier backups — your data volume is scoped to your app
Before you start
You will need:
- SSH access to
vibe-dev.emerson.edu - Your app located in
/opt/apps/<your-app-name> - Your current database name, user, and password from your
.envfile - A port in the
545xrange that isn't already in use (check withsudo docker ps --format "table {{.Ports}}")
Step 1 — Export your existing data
Before moving off the shared database, export your data so you can import it into your new dedicated container.
docker exec postgres pg_dump -U postgres <your_database_name> > /opt/apps/<your-app-name>/backup.sql
Verify the dump looks reasonable:
head -20 /opt/apps/<your-app-name>/backup.sql
Step 2 — Update your docker-compose.yml
Add a db service and a named volume to your existing docker-compose.yml. Below is the standard template — replace all <placeholders> before using.
services:
web:
# ... your existing web service definition, unchanged ...
db:
image: postgres:17
container_name: <your-app-name>_postgres
restart: always
ports:
- "<545x>:5432" # Replace 545x with your assigned port, e.g. 5452
environment:
- POSTGRES_PASSWORD=<your-db-password>
volumes:
- <your-app-name>_postgres:/var/lib/postgresql/data
volumes:
<your-app-name>_postgres:
Key things to change in your web service:
Update your DATABASE_URL environment variable (or .env file) from pointing at host.docker.internal:5432 to pointing at the db service instead:
# Before (shared database) DATABASE_URL=postgresql://postgres:<password>@host.docker.internal:5432/<your_database_name> # After (dedicated database) DATABASE_URL=postgresql://postgres:<password>@db:5432/<your_database_name>
Also add a dependency so your web service waits for the database to be ready:
web:
depends_on:
- db
Step 3 — Deploy the updated stack
From your app directory:
cd /opt/apps/<your-app-name> docker compose up -d
This will start your new dedicated postgres container alongside your web service.
Step 4 — Import your data
Wait a few seconds for postgres to initialize, then import your dump:
docker exec -i <your-app-name>_postgres psql -U postgres -c "CREATE DATABASE <your_database_name>;" docker exec -i <your-app-name>_postgres psql -U postgres <your_database_name> < /opt/apps/<your-app-name>/backup.sql
Verify the import:
docker exec -it <your-app-name>_postgres psql -U postgres -d <your_database_name> -c "\dt"
Step 5 — Test your application
Hit your app and verify everything works as expected with the new database. Check logs if anything looks off:
docker compose logs -f
Step 6 — Clean up the shared database
Once you've confirmed your app is working correctly with its dedicated database, drop your database from the shared instance to free up resources:
docker exec postgres psql -U postgres -c "DROP DATABASE <your_database_name>;"
Also delete your backup file if you no longer need it:
rm /opt/apps/<your-app-name>/backup.sql
Using Portainer instead of the CLI
If you prefer a GUI, you can deploy and manage your stack through Portainer at https://vibe-dev.emerson.edu:9443.
- Go to Stacks → Add stack
- Give it the same name as your app directory (e.g.
myapp) - Paste your updated
docker-compose.ymlinto the web editor - Note: if your compose file uses
env_file, you'll need to inline your environment variables directly in the compose editor — Portainer cannot read files from disk - Click Deploy the stack
Portainer is optional — CLI deployments work just as well and are required for apps that use env_file or build: directives.
Reference: complete example
Here is a complete example for an app called myapp using port 5452:
services:
web:
image: localhost:5443/myapp:latest
container_name: myapp
restart: always
ports:
- "8090:8000"
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- /opt/apps/myapp:/app
environment:
- DATABASE_URL=postgresql://postgres:mysecretpassword@db:5432/myapp_db
depends_on:
- db
db:
image: postgres:17
container_name: myapp_postgres
restart: always
ports:
- "5452:5432"
environment:
- POSTGRES_PASSWORD=mysecretpassword
volumes:
- myapp_postgres:/var/lib/postgresql/data
volumes:
myapp_postgres:
Port assignments
Postgres ports start at 5450 and increment per app. Check what's already in use before picking yours:
sudo docker ps --format "table {{.Names}}\t{{.Ports}}" | grep 54
Current known assignments:
| App | Postgres Port |
|---|---|
| emersonformsportal | 5450 |
| castletravel | 5451 |
| (your app) | 5452+ |
Need help?
Contact the infrastructure team or open a ticket with IT.