Skip to content

Docker Guide

Comprehensive Docker Compose guide for the Loryth Butterfly microservices platform.

For initial setup, see the Quick Start. For a server behind an existing proxy, follow the server deployment guide.

Architecture Overview

Client (port 80)
    |
Nginx Gateway (path-based routing)
    |-- / --> Web UI (React+Vite SPA)
    |-- /api/v1/iam/*     --> loryth-iam-api:8000
    |-- /api/v1/cms/*     --> loryth-cms-api:8000
    |-- /api/v1/grocery/* --> loryth-grocery-api:8000
    |-- /api/v1/issues/*  --> loryth-issues-api:8000
    |-- /api/v1/journal/* --> loryth-journal-api:8000
    +-- /api/v1/wallet/*  --> loryth-wallet-api:8000

Infrastructure:
- PostgreSQL 17.4 (one database and role per service)
- RabbitMQ 4.0.8 (loryth vhost)
- MinIO (object storage)

Services (12 containers):
- 6 FastAPI API services
- 6 Background workers

Services Reference

Infrastructure

Service Image Purpose
postgres Custom PostgreSQL 17.4 with pgvector Nine isolated service databases
rabbitmq rabbitmq:4.0.8-management-alpine Message broker with loryth vhost
minio minio/minio:latest Object storage

API Services (FastAPI on internal port 8000)

Service Description
loryth-iam-api Identity & Access Management
loryth-cms-api Content Management System
loryth-grocery-api Grocery list management
loryth-issues-api Issue tracking
loryth-journal-api Personal journal
loryth-wallet-api Financial tracking

Worker Services (Background Job Processors)

Each API service has a corresponding background worker: loryth-iam-worker, loryth-cms-worker, loryth-grocery-worker, loryth-issues-worker, loryth-journal-worker, loryth-wallet-worker.

Presentation & Gateway

Service Description
web React+Vite SPA served via nginx
gateway Nginx reverse proxy (port 80)

Service Ports (Development)

These ports are exposed by docker-compose.override.yml in development mode:

Service Port(s)
Gateway 80
PostgreSQL 5432
RabbitMQ 5672 (AMQP), 15672 (Management)
MinIO 9000 (API), 9001 (Console)
IAM API 8001
CMS API 8002
Grocery API 8003
Issues API 8004
Journal API 8005
Wallet API 8006
Web UI (Vite) 3000

Development Mode

Development mode is enabled by default via docker-compose.override.yml.

Features

  • Source code hot-reload via bind mounts
  • fastapi dev for automatic API reload on code changes
  • Vite HMR for React UI
  • Debug logging (LOG_LEVEL=DEBUG)
  • Direct port access to all services (see table above)

Development Workflow

# Start all services
docker compose up -d

# Edit code locally — changes are reflected immediately
# (FastAPI auto-reloads, Vite HMR for UI)

# View specific service logs
docker compose logs -f loryth-grocery-api

# Restart a single service
docker compose restart loryth-grocery-api

# Rebuild after dependency changes
docker compose build loryth-grocery-api
docker compose up -d loryth-grocery-api

# Run tests
docker compose exec loryth-grocery-api pytest

# Run tests with coverage
docker compose exec loryth-grocery-api pytest --cov

Production Mode

Run without the development override file:

# Stop dev environment
docker compose down

# Start in production mode (no overrides)
docker compose -f docker-compose.yml up -d

# Or disable the override file
mv docker-compose.override.yml docker-compose.override.yml.disabled
docker compose up -d

Production Features

  • Optimized builds without bind mounts
  • fastapi run (no auto-reload)
  • LOG_LEVEL=INFO
  • No direct port exposure (only gateway on port 80)

Security Checklist

  • Change all default passwords in .env
  • Use strong passwords (20+ characters)
  • Enable HTTPS/TLS on the gateway
  • Restrict port exposure (only gateway ports)
  • Use Docker secrets instead of environment variables
  • Enable firewall rules
  • Regular security updates
  • Set up monitoring and alerting

Common Commands

Start / Stop

# Start all services
docker compose up -d

# Stop all services
docker compose down

# Stop and remove volumes (clean slate)
docker compose down -v

# Restart all services
docker compose restart

# Restart specific service
docker compose restart loryth-grocery-api

# Start specific services
docker compose up -d postgres rabbitmq loryth-iam-api

Logs

# View all logs
docker compose logs

# Follow logs
docker compose logs -f

# Specific service logs
docker compose logs -f loryth-grocery-api

# Last 100 lines
docker compose logs --tail=100 loryth-iam-api

# Multiple services
docker compose logs -f postgres rabbitmq

Build

# Build all images
docker compose build

# Build specific service
docker compose build loryth-grocery-api

# Force rebuild (no cache)
docker compose build --no-cache loryth-grocery-api

# Build and start
docker compose up -d --build

Status

# List all containers
docker compose ps

# Check health status
docker compose ps | grep healthy

# Container details
docker compose ps loryth-grocery-api

Container Access

# Shell into a container
docker compose exec loryth-grocery-api bash

# Run one-off command
docker compose run --rm loryth-grocery-api python -m pytest

# Root shell
docker compose exec -u root loryth-grocery-api bash

Database Operations

Access

# Connect to PostgreSQL
docker compose exec postgres psql -U loryth -d postgres

# List databases
docker compose exec postgres psql -U loryth -c '\l'

# Connect to iam database
docker compose exec postgres psql -U loryth -d iam

# Connect to grocery database
docker compose exec postgres psql -U grocery -d grocery

Migrations

# Run migrations again
docker compose up migrations

# Check migration logs
docker compose logs migrations

# Force re-run
docker compose run --rm migrations

Backup & Restore

# Backup
docker compose exec postgres pg_dump -U loryth iam > iam_backup.sql

# Restore
cat iam_backup.sql | docker compose exec -T postgres psql -U loryth -d iam

RabbitMQ Management

# Management UI (development mode)
# URL: http://localhost:15672
# Username: loryth / Password: from .env RABBITMQ_PASSWORD

# List queues
docker compose exec rabbitmq rabbitmqctl list_queues -p loryth

# List exchanges
docker compose exec rabbitmq rabbitmqctl list_exchanges -p loryth

# Check connections
docker compose exec rabbitmq rabbitmqctl list_connections

MinIO Console

# Console (development mode)
# URL: http://localhost:9001
# Username/Password: from .env MINIO_ROOT_USER / MINIO_ROOT_PASSWORD

# Create bucket
docker compose exec minio mc mb local/loryth-cms

# List buckets
docker compose exec minio mc ls local/

Health Checks

All services expose /health endpoints:

# Gateway health
curl http://localhost/health

# Service health (via gateway)
curl http://localhost/api/v1/iam/health
curl http://localhost/api/v1/cms/health
curl http://localhost/api/v1/grocery/health
curl http://localhost/api/v1/issues/health
curl http://localhost/api/v1/journal/health
curl http://localhost/api/v1/wallet/health

# Direct service health (development mode)
curl http://localhost:8001/health  # IAM
curl http://localhost:8002/health  # CMS
curl http://localhost:8003/health  # Grocery
curl http://localhost:8004/health  # Issues
curl http://localhost:8005/health  # Journal
curl http://localhost:8006/health  # Wallet

Troubleshooting

Services Won't Start

# Check container status
docker compose ps

# View logs for failed service
docker compose logs loryth-iam-api

# Restart unhealthy service
docker compose restart loryth-grocery-api

# Rebuild problematic service
docker compose build --no-cache loryth-grocery-api
docker compose up -d loryth-grocery-api

Database Connection Issues

# Verify postgres is healthy
docker compose ps postgres

# Check postgres logs
docker compose logs postgres

# Test connection
docker compose exec postgres psql -U loryth -c 'SELECT 1'

Port Conflicts

If a port is already in use:

  1. Find conflicting process: lsof -i :80
  2. Stop the conflicting service
  3. Or change the port in docker-compose.yml / docker-compose.override.yml

Clean Slate

# Stop everything and remove volumes
docker compose down -v

# Remove all containers and images
docker compose down --rmi all -v

# Start fresh
docker compose up -d

Docker Resources

# Check disk usage
docker system df

# Prune unused resources
docker system prune -a

Environment Variables

Key variables in .env:

# Project
COMPOSE_PROJECT_NAME=loryth
ENVIRONMENT=development

# PostgreSQL
POSTGRES_USER=loryth
POSTGRES_PASSWORD=secure_password

# RabbitMQ
RABBITMQ_USERNAME=loryth
RABBITMQ_PASSWORD=secure_password
RABBITMQ_VHOST=loryth

# MinIO
MINIO_ROOT_USER=access_key
MINIO_ROOT_PASSWORD=secret_key

# Logging
LOG_LEVEL=INFO  # or DEBUG for development

Network Architecture

All services run on loryth-network (bridge driver):

  • Services communicate via internal DNS using service names as hostnames (e.g., postgres, rabbitmq, loryth-iam-api)
  • Gateway exposes services externally on port 80

Volumes and Data Persistence

Named volumes for data persistence:

Volume Purpose
postgres-data PostgreSQL data directory
rabbitmq-data RabbitMQ data and config
minio-data MinIO object storage
# List volumes
docker volume ls | grep loryth

# Inspect volume
docker volume inspect loryth_postgres-data

# Remove all volumes (CAUTION: data loss)
docker compose down -v

Data persists across docker compose down and docker compose up cycles. Only docker compose down -v removes volumes.

Scaling

# Run multiple instances of a service
docker compose up --scale loryth-grocery-api=3

# Note: Gateway nginx needs load-balancing configuration for scaled services

Useful Aliases

Add to your .bashrc or .zshrc:

alias dc='docker compose'
alias dcu='docker compose up -d'
alias dcd='docker compose down'
alias dcl='docker compose logs -f'
alias dcp='docker compose ps'
alias dcr='docker compose restart'
alias dcb='docker compose build'