MeshWorld India LogoMeshWorld.
HowToPostgreSQLDockerDatabaseDocker ComposeDeveloper ToolsBackend5 min read

Run PostgreSQL Locally with Docker in Under 2 Minutes

Vishnu
By Vishnu
|Updated: Mar 11, 2026
Run PostgreSQL Locally with Docker in Under 2 Minutes

Running PostgreSQL locally used to mean a full install, fighting with config files, and dealing with version conflicts. With Docker, it’s a one-liner — and you can have multiple versions running side by side if you need them.


Quick start — running in 60 seconds

docker run -d \
  --name postgres \
  -e POSTGRES_USER=myuser \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_DB=mydb \
  -p 5432:5432 \
  postgres:16-alpine

That’s it. PostgreSQL 16 is running on localhost:5432.

Connect with psql:

# Using Docker (no local psql needed)
docker exec -it postgres psql -U myuser mydb

# Using local psql if you have it installed
psql -h localhost -U myuser mydb

Check it’s running:

docker ps
# CONTAINER ID  IMAGE              PORTS                   NAMES
# abc123        postgres:16-alpine 0.0.0.0:5432->5432/tcp  postgres

The problem with the quick start: data disappears

When you docker rm the container, all your data goes with it. For serious development, you need persistent storage.


Proper setup — with persistent storage

docker run -d \
  --name postgres \
  -e POSTGRES_USER=myuser \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_DB=mydb \
  -p 5432:5432 \
  -v postgres_data:/var/lib/postgresql/data \
  --restart unless-stopped \
  postgres:16-alpine

The -v postgres_data:/var/lib/postgresql/data flag creates a Docker named volume. Your data lives in that volume even if you remove and recreate the container.

To see your volumes:

docker volume ls
# DRIVER    VOLUME NAME
# local     postgres_data

docker-compose — for real projects

For any project you’re actively developing, use docker-compose.yml so your database config lives next to your code:

services:
  db:
    image: postgres:16-alpine
    container_name: myapp_db
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U myuser -d mydb"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:

Start it:

docker compose up -d

# Check it's healthy
docker compose ps
# NAME         STATUS          PORTS
# myapp_db     Up (healthy)    0.0.0.0:5432->5432/tcp

Stop and restart without losing data:

docker compose stop   # stops containers, data stays
docker compose start  # starts again
docker compose down   # removes containers, data STAYS in volume
docker compose down -v # removes containers AND volumes (data gone)

Connecting from your application

Your .env file:

DATABASE_URL=postgresql://myuser:mypassword@localhost:5432/mydb

Connection string format:

postgresql://[user]:[password]@[host]:[port]/[database]

Works with any client:

  • Prisma: datasource db { url = env("DATABASE_URL") }
  • node-postgres (pg): new Pool({ connectionString: process.env.DATABASE_URL })
  • SQLAlchemy: create_engine(os.environ["DATABASE_URL"])
  • GORM: built-in postgres dialect

Connect with a GUI client

Your Docker PostgreSQL is just a regular postgres server on port 5432. Connect with any GUI tool:

ToolConnection
TablePlusHost: localhost, Port: 5432, User/DB/Pass as set
DBeaverSame — PostgreSQL connection type
pgAdminAdd server: localhost:5432
DataGripNew data source → PostgreSQL
VS CodeSQLTools extension → PostgreSQL driver

Running multiple PostgreSQL versions

Docker makes version testing trivial:

# PostgreSQL 14 on port 5433
docker run -d --name pg14 \
  -e POSTGRES_PASSWORD=pass \
  -p 5433:5432 \
  postgres:14-alpine

# PostgreSQL 16 on port 5432
docker run -d --name pg16 \
  -e POSTGRES_PASSWORD=pass \
  -p 5432:5432 \
  postgres:16-alpine

Connect to whichever you need by changing the port.


Load a SQL dump into the container

# Pipe a dump file into psql inside the container
docker exec -i postgres psql -U myuser mydb < backup.sql

# Or copy the file in first
docker cp backup.sql postgres:/tmp/
docker exec -it postgres psql -U myuser mydb -f /tmp/backup.sql

Dump the database out of the container

# Dump to local file
docker exec postgres pg_dump -U myuser mydb > backup.sql

# Compressed dump
docker exec postgres pg_dump -U myuser -Fc mydb > backup.dump

Common commands

# See container logs
docker logs postgres
docker logs -f postgres  # follow

# Enter a bash shell inside the container
docker exec -it postgres bash

# Connect to psql directly
docker exec -it postgres psql -U myuser mydb

# Restart the container
docker restart postgres

# Stop without removing
docker stop postgres

# Remove container (data stays if you used a volume)
docker rm postgres

# Remove container and volume
docker stop postgres && docker rm postgres
docker volume rm postgres_data

Environment variables reference

VariableRequiredDefaultWhat it sets
POSTGRES_PASSWORDYesPassword for the user
POSTGRES_USERNopostgresUsername
POSTGRES_DBNoSame as userDefault database
PGDATANo/var/lib/postgresql/dataData directory

The Docker setup takes about 60 seconds and gives you a clean, isolated database that you can tear down and rebuild any time. No leftover system packages, no version conflicts, no permission issues.

Keep these handy: PostgreSQL Cheat Sheet | How to Debug a Slow SQL Query

Share_This Twitter / X
Vishnu
Written By

Vishnu

Founder & Principal Architect at MeshWorld. Senior engineer and instructor specializing in AI agent systems, scalable web architecture, and modern development workflows.

Enjoyed this article?

Support MeshWorld and help us create more technical content