A simple Docker Compose configuration for running PostgreSQL with persistent data storage and easy configuration.
- PostgreSQL Docker Setup
- Docker
- Docker Compose
-
Clone or download this repository
-
Start PostgreSQL:
docker-compose up -d
-
Connect to PostgreSQL:
# Using Docker exec docker-compose exec postgres psql -U postgres -d myapp # Or using any PostgreSQL client psql -h localhost -p 5432 -U postgres -d myapp
-
Access pgAdmin4 Web Interface:
- Open http://localhost:8080 in your browser
- Login with email:
[email protected]
and password:admin
- Add a new server connection to
postgres:5432
Copy the example environment file and customize as needed:
cp .env.example .env
Available environment variables:
Variable | Default | Description |
---|---|---|
POSTGRES_DB |
myapp |
Default database name |
POSTGRES_USER |
postgres |
PostgreSQL username |
POSTGRES_PASSWORD |
password |
PostgreSQL password |
PGADMIN_DEFAULT_EMAIL |
[email protected] |
pgAdmin4 login email |
PGADMIN_DEFAULT_PASSWORD |
admin |
pgAdmin4 login password |
You can modify the docker-compose.yml
file to:
- Change the exposed ports (PostgreSQL: 5432, pgAdmin4: 8080)
- Add additional PostgreSQL configuration
- Mount custom configuration files
- Customize pgAdmin4 settings and authentication
Data is automatically persisted using Docker volumes:
- PostgreSQL Data:
- Volume:
postgres_data
- Mount Point:
/var/lib/postgresql/data
- Volume:
- pgAdmin4 Data:
- Volume:
pgadmin_data
- Mount Point:
/var/lib/pgadmin
- Volume:
Your data and pgAdmin4 configuration will survive container restarts and updates.
This setup includes pgAdmin4, a web-based PostgreSQL administration tool that provides a graphical interface for managing your databases.
-
Start the services:
docker-compose up -d
-
Open pgAdmin4 in your browser:
- URL: http://localhost:8080
- Email:
[email protected]
- Password:
admin
Once logged into pgAdmin4:
-
Add New Server:
- Right-click "Servers" in the left panel
- Select "Register" > "Server..."
-
Configure Connection:
- General Tab:
- Name:
PostgreSQL Docker
(or any name you prefer)
- Name:
- Connection Tab:
- Host name/address:
postgres
(the service name from docker-compose) - Port:
5432
- Username:
postgres
- Password:
password
- Host name/address:
- General Tab:
-
Save and Connect: Click "Save" to establish the connection
You can now use pgAdmin4's graphical interface to:
- Browse databases and schemas
- Run SQL queries
- Create and modify tables
- View data
- Monitor database performance
- Import/export data
Place SQL files in the init-scripts/
directory to run them automatically when the database is first created:
mkdir init-scripts
echo "CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(100));" > init-scripts/01-create-tables.sql
Scripts are executed in alphabetical order.
This setup includes a sample schema (01-create-schema.sql
) that creates:
- Schema:
app
- A dedicated schema for application tables - Tables:
app.users
- User accounts with username, email, and profile infoapp.products
- Product catalog with pricing and inventoryapp.orders
- Customer orders with status trackingapp.order_items
- Individual items within orders
- Sample Data: Pre-populated with example users and products
- Indexes: Optimized for common queries
- View:
app.order_summary
- Convenient order overview
To explore the schema:
# Connect to database
docker-compose exec postgres psql -U postgres -d myapp
# List all schemas
\dn
# Set search path to include app schema
SET search_path TO app, public;
# List tables in the app schema
\dt app.*
# View sample data
SELECT * FROM app.users;
SELECT * FROM app.products;
SELECT * FROM app.order_summary;
docker-compose up -d
docker-compose down
docker-compose logs -f postgres
# Interactive shell
docker-compose exec postgres psql -U postgres -d myapp
# Execute single command
docker-compose exec postgres psql -U postgres -d myapp -c "SELECT version();"
docker-compose exec postgres pg_dump -U postgres myapp > backup.sql
docker-compose exec -T postgres psql -U postgres myapp < backup.sql
docker-compose down -v # Removes volumes and data
docker-compose up -d
# Connect and set search path
docker-compose exec postgres psql -U postgres -d myapp -c "SET search_path TO app, public;"
# Query sample data
docker-compose exec postgres psql -U postgres -d myapp -c "SET search_path TO app, public; SELECT username, email FROM users;"
# View product catalog
docker-compose exec postgres psql -U postgres -d myapp -c "SET search_path TO app, public; SELECT name, price, category FROM products;"
# Check database structure
docker-compose exec postgres psql -U postgres -d myapp -c "\dt app.*"
# Create a sample order (interactive session recommended)
docker-compose exec postgres psql -U postgres -d myapp
Example queries to try in the interactive session:
-- Set search path
SET search_path TO app, public;
-- Create a sample order
INSERT INTO orders (user_id, total_amount, status)
VALUES (1, 1029.98, 'pending');
-- Add items to the order
INSERT INTO order_items (order_id, product_id, quantity, unit_price)
VALUES
(1, 1, 1, 999.99), -- Laptop
(1, 2, 1, 29.99); -- Wireless Mouse
-- View the order summary
SELECT * FROM order_summary WHERE order_id = 1;
The container includes a health check that verifies PostgreSQL is accepting connections:
# Check container health
docker-compose ps
-
Ports already in use:
- PostgreSQL: Change the port mapping in
docker-compose.yml
from5432:5432
to5433:5432
- pgAdmin4: Change the port mapping from
8080:80
to8081:80
- Connect using:
psql -h localhost -p 5433 -U postgres -d myapp
- Access pgAdmin4 at: http://localhost:8081
- PostgreSQL: Change the port mapping in
-
Permission denied errors:
- Ensure Docker has proper permissions
- On Linux, you may need to run with
sudo
-
Data not persisting:
- Check that the volume is properly mounted
- Verify with:
docker volume ls
-
Connection refused:
- Wait for the container to fully start (check logs)
- Verify the container is running:
docker-compose ps
# Check container status
docker-compose ps
# View detailed logs
docker-compose logs postgres
# Access container shell
docker-compose exec postgres bash
# Check PostgreSQL processes
docker-compose exec postgres ps aux
# Monitor resource usage
docker stats
For production use, consider:
- Change default passwords: Use strong, unique passwords
- Limit network access: Configure firewall rules
- Use secrets: Store sensitive data in Docker secrets
- Regular updates: Keep PostgreSQL image updated
- Backup strategy: Implement automated backups
If you prefer to run PostgreSQL locally without Docker, you can install it using Homebrew:
# Install PostgreSQL
brew install postgresql@15
# Or install the latest version
brew install postgresql
# Install pgAdmin (PostgreSQL administration tool)
brew install --cask pgadmin4
# Start PostgreSQL service
brew services start postgresql@15
# Stop PostgreSQL service
brew services stop postgresql@15
# Restart PostgreSQL service
brew services restart postgresql@15
# Check service status
brew services list | grep postgresql
# Create a database
createdb myapp
# Connect to database
psql myapp
# Connect as specific user
psql -U postgres myapp
# List all databases
psql -l
# Drop a database
dropdb myapp
pgAdmin is a web-based PostgreSQL administration tool that provides a graphical interface for managing databases.
# Launch pgAdmin
open -a pgAdmin\ 4
# Or find it in Applications folder
# Applications > pgAdmin 4
Setting up pgAdmin connection:
- Open pgAdmin (it will launch in your web browser)
- Click "Add New Server"
- Configure the connection:
- Name: Local PostgreSQL (or any name you prefer)
- Host: localhost
- Port: 5432
- Username: Your system username (or postgres if configured)
- Password: Leave blank if no password is set, or enter your password
- Default Port: 5432
- Default User: Your system username
- Data Directory:
/opt/homebrew/var/postgresql@15/
(Apple Silicon) or/usr/local/var/postgresql@15/
(Intel) - Config File:
/opt/homebrew/etc/postgresql@15/postgresql.conf
If you want to get started with PostgreSQL instantly without any local setup, you can use Neon Launchpad - a tool that provides instant, hosted PostgreSQL databases in seconds with no signup required.
The fastest way to get a PostgreSQL database:
- Go to neon.new in your browser
- Get instant database credentials - you'll receive a connection string immediately
- Use it like any PostgreSQL database - works with any PostgreSQL-compatible tool
For command-line users and automation:
# Get an instant PostgreSQL database
npx neondb
This will:
- Create a real, hosted PostgreSQL database in 2 seconds
- Generate a
.env
file with standard environment variables - Provide both direct and pooled connection strings
Example output in your .env
file:
# Claimable DB expires at: {{ date string }}
# Claim it now to your account: https://neon.new/database/{{hash}}
DATABASE_URL=postgresql://...
DATABASE_URL_POOLER=postgresql://...
You can also use it with options:
# Skip prompts and use defaults
npx neondb --yes
# Specify custom .env file location
npx neondb --env ./custom/.env
# Set custom database URL key
npx neondb --key DB_CONNECTION_STRING
The connection strings work with any PostgreSQL-compatible framework or tool:
# Connect using psql
psql $DATABASE_URL
# Use with your application
# The DATABASE_URL environment variable is automatically set
You can also use it to seed your database with the existing schema:
# Apply your initialization scripts
psql $DATABASE_URL < init-scripts/01-create-schema.sql
Databases created with Neon Launchpad:
- Last 72 hours by default - perfect for development and testing
- Can be claimed later - visit the claim URL provided to link it to a Neon account
- Zero downtime claiming - your connection strings continue to work after claiming
- No interruptions - your application stays connected during the claim process
To claim your database:
- Visit the claim URL provided in the CLI output or
.env
file - Create a Neon account or sign in
- The database is instantly linked to your account with no downtime
This makes Neon Launchpad perfect for:
- Quick prototyping - get a database instantly
- Development workflows - no local setup required
- CI/CD pipelines - fresh databases for each test run
- Demos and tutorials - share working databases instantly
- AI agents and platforms - programmatic database provisioning
This setup uses postgres:latest
, which currently points to PostgreSQL 16. To use a specific version:
services:
postgres:
image: postgres:15 # or postgres:14, postgres:13, etc.