Docker Compose Setup Guide

Redis + Postgres Example - Complete setup in under 5 minutes

Updated 2025
5 min read
Beginner

What You'll Build

In this guide, you'll learn how to run Redis and Postgres together using Docker Compose — a perfect base for caching and data storage in modern applications. This setup is ideal for development, testing, and even small production deployments.

By the end of this guide, you'll have a fully functional multi-container application with persistent data storage, caching layer, and proper networking between services.

What You'll Need

Prerequisites

  • Docker & Docker Compose installed

    Install Docker Compose →

  • Basic terminal knowledge

    Comfortable with command line operations

  • 2GB+ free disk space

    For Docker images and data volumes

Docker Compose YAML File

Complete docker-compose.yml

Copy this file to your project directory and customize as needed

docker-compose.yml

Click the copy button to copy this configuration

version: '3.9'

services:
  postgres:
    image: postgres:16
    container_name: postgres
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: appdb
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d appdb"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:
  redis_data:

Pro Tip

This configuration includes health checks and persistent volumes. The data will survive container restarts and updates, making it perfect for development and production use.

Service Breakdown

PostgreSQL Service

Configuration Details

  • Image: postgres:16 (latest stable)
  • Port: 5432 (standard PostgreSQL port)
  • Database: appdb
  • User: user
  • Password: password

Environment Variables

POSTGRES_USER=user
POSTGRES_PASSWORD=password
POSTGRES_DB=appdb

Connection String

postgresql://user:password@localhost:5432/appdb

Redis Service

Configuration Details

  • Image: redis:7 (latest stable)
  • Port: 6379 (standard Redis port)
  • Persistence: Enabled with volume
  • Memory: No limit (adjust as needed)

Connection Details

Host: localhost
Port: 6379
Password: (none by default)

Redis CLI Connection

redis-cli -h localhost -p 6379

Run the Setup

Step-by-Step Instructions

1. Start the Services

Run this command in your project directory:

docker compose up -d

The -d flag runs containers in detached mode (background).

2. Verify Services are Running

Check the status of your containers:

docker compose ps

You should see both postgres and redis containers with "Up" status.

3. Check Service Health

View the logs to ensure services are healthy:

docker compose logs

Look for "ready to accept connections" (Postgres) and "Ready to accept connections" (Redis).

4. Test Database Connection

Test your PostgreSQL connection:

# Connect to PostgreSQL
docker exec -it postgres psql -U user -d appdb

# In psql, run:
\l
\q

This will connect to the database and list all databases. Type \\q to exit.

5. Test Redis Connection

Test your Redis connection:

# Connect to Redis
docker exec -it redis redis-cli

# In Redis CLI, run:
ping
set test "Hello World"
get test
exit

This will test Redis connectivity and basic operations. Type exit to quit.

Customization Options

Environment Variables

Create a .env file to customize your setup:

.env

Copy this template and customize the values

# .env file
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=mydatabase
POSTGRES_PORT=5432
REDIS_PORT=6379

Then update your docker-compose.yml to use these variables:

environment:
  POSTGRES_USER: ${POSTGRES_USER}
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
  POSTGRES_DB: ${POSTGRES_DB}

Adding More Services

You can easily add more services to your stack. Here's how to add a web application:

services:
  # ... existing postgres and redis services ...
  
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://user:password@postgres:5432/appdb
      - REDIS_URL=redis://redis:6379
    depends_on:
      - postgres
      - redis

Troubleshooting Common Issues

Problem: Port Already in Use

Symptoms

Error: "bind: address already in use" when starting containers.

Solutions

1. Check what's using the port:

# On Linux/Mac\nsudo lsof -i :5432\n\n# On Windows\nnetstat -ano | findstr :5432

2. Change the port mapping:

ports:\n  - '5433:5432'  # Use 5433 instead of 5432

3. Stop conflicting services:

docker compose down\n# or stop local postgres/redis services

Problem: Services Can't Connect

Symptoms

Your application can't connect to the database or Redis, even though containers are running.

Solutions

1. Use service names for internal communication:

# Instead of localhost, use service names\nDATABASE_URL=postgresql://user:password@postgres:5432/appdb\nREDIS_URL=redis://redis:6379

2. Check if services are on the same network:

docker network ls\ndocker network inspect <network_name>

3. Wait for services to be ready:

# Add depends_on with condition\ndepends_on:\n  postgres:\n    condition: service_healthy\n  redis:\n    condition: service_healthy

Problem: Data Not Persisting

Symptoms

Data disappears when containers are restarted or recreated.

Solutions

1. Ensure volumes are properly defined:

volumes:\n  postgres_data:\n  redis_data:

2. Check volume mounts in services:

volumes:\n  - postgres_data:/var/lib/postgresql/data\n  - redis_data:/data

3. Verify volumes exist:

docker volume ls\ndocker volume inspect <volume_name>

Docker Compose Best Practices for 2025

  • Use environment variables for sensitive data

    Never hardcode passwords or API keys in your docker-compose.yml file.

  • Always use health checks

    Health checks ensure services are ready before dependent services start.

  • Use named volumes for data persistence

    Named volumes are easier to manage than bind mounts for most use cases.

  • Keep services on the same network

    Docker Compose automatically creates a network, but be explicit about dependencies.

  • Use specific image tags

    Avoid latest tag in production. Use specific versions like postgres:16.

Quick Command Reference

docker compose up -d

Start services in background

docker compose down

Stop and remove containers

docker compose ps

List running services

docker compose logs

View service logs

docker compose restart

Restart all services

docker compose exec postgres psql -U user -d appdb

Connect to PostgreSQL