Setting Up Local PostgreSQL with Docker Compose

October, 28th 2024 2 min read

Local PostgreSQL Using Docker Compose

Running PostgreSQL in Docker is one of the most reliable ways to develop locally without installing PostgreSQL directly onto your system. Docker Compose simplifies the entire lifecycle: creating containers, managing volumes, setting configuration, and linking services like pgAdmin.

This updated guide includes improved configuration, optional pgAdmin support, health checks, persistent storage, and environment safety tips.

Prerequisites

You need the following installed:

  • Docker
  • Docker Compose
  • Optional: pgAdmin or DBeaver for GUI management

Step 1: Create a Project Directory

bash
mkdir postgres-docker
cd postgres-docker

Organizing your PostgreSQL setup inside a dedicated project folder keeps your environment clean and portable.


Step 2: Create an Improved docker-compose.yml

The following configuration includes:

  • PostgreSQL with persistent storage
  • Optional initialization SQL scripts
  • Health checks
  • A dedicated network
  • Optional pgAdmin container
yaml
version: '3.9'

services:
  postgres:
    image: postgres:16
    container_name: local-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: postgres_user
      POSTGRES_PASSWORD: postgres_password
      POSTGRES_DB: postgres_db
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init:/docker-entrypoint-initdb.d
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres_user"]
      interval: 5s
      timeout: 3s
      retries: 5
    networks:
      - pgnet

  pgadmin:
    image: dpage/pgadmin4:latest
    container_name: pgadmin
    restart: unless-stopped
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@example.com
      PGADMIN_DEFAULT_PASSWORD: admin123
    ports:
      - "5050:80"
    depends_on:
      - postgres
    networks:
      - pgnet

volumes:
  postgres_data:

networks:
  pgnet:

Features added in this improved version

  • Health checks ensure PostgreSQL is ready before other services connect.
  • pgAdmin service gives you a full GUI at http://localhost:5050.
  • Initialization folder (./init) lets you pre-load tables, schemas, or seed data.
  • Named Docker network isolates database traffic.

Step 3: Optional SQL Initialization

Create an init folder:

bash
mkdir init

Then add init/001-create-tables.sql:

sql
CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  email TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

This script runs automatically when the container is first created.


Step 4: Start the Services

bash
docker-compose up -d

This pulls the images, creates the containers, and initializes your PostgreSQL database.

Check running services:

bash
docker ps

Step 5: Connect to PostgreSQL

Using psql:

bash
psql -h localhost -p 5432 -U postgres_user -d postgres_db

Using pgAdmin:

Open:

plaintext
http://localhost:5050

Add a new server:

  • Host: postgres
  • User: postgres_user
  • Password: postgres_password

Step 6: Stop and Remove Containers Safely

bash
docker-compose down

Volumes persist, so your data remains intact.

To remove everything including data:

bash
docker-compose down -v

Step 7: Useful Commands

Restart PostgreSQL

bash
docker-compose restart postgres

Reset the database completely

bash
docker-compose down -v
docker-compose up -d

Enter PostgreSQL shell inside container

bash
docker exec -it local-postgres psql -U postgres_user -d postgres_db

Tips and Best Practices

Use .env instead of hardcoding credentials

Create .env:

plaintext
POSTGRES_USER=postgres_user
POSTGRES_PASSWORD=postgres_password
POSTGRES_DB=postgres_db

And replace variables in docker-compose.yml.

Always mount a persistent volume

Never rely on container-only storage.

Use versioned SQL migrations

Use tools like:

  • Flyway
  • Prisma Migrate
  • Liquibase

Summary

You now have a fully-featured PostgreSQL instance running locally with Docker Compose. This setup is production-like, supports persistence, enables optional pgAdmin GUI management, and gives you complete control over initialization and networking.

This environment is ideal for:

  • Local development
  • API testing
  • Microservice environments
  • Team-shared reproducible setups