Docker Deployment
This guide explains how to set up and manage the Grant infrastructure services using Docker Compose.
Overview
The Grant uses Docker Compose to manage its infrastructure services:
- PostgreSQL 16 - Primary database
- PgAdmin 4 - Database management UI
- Redis 7 - Caching layer (optional)
Quick Start
1. Configure Infrastructure
# Copy the infrastructure environment template
cp .env.example .env
# Edit if needed (optional - defaults work for development)
vim .env2. Start Services
# Start all services
docker-compose up -d
# Or start specific services
docker-compose up -d postgres redis3. Verify Services
# Check service status
docker-compose ps
# View logs
docker-compose logs -f
docker-compose logs -f postgres # specific service4. Configure API
# Copy API environment template
cp apps/api/.env.example apps/api/.env
# The default DB_URL already matches docker-compose settings
# DB_URL=postgresql://grant_user:grant_password@localhost:5432/grant5. Run API
cd apps/api
pnpm run devEnvironment Configuration
Root .env (Infrastructure)
Controls Docker Compose services:
# Database
POSTGRES_DB=grant # Database name
POSTGRES_USER=grant_user # Database user
POSTGRES_PASSWORD=grant_password # Database password
# PgAdmin
PGADMIN_EMAIL=admin@grant.dev # Login email
PGADMIN_PASSWORD=grant_password # Login password
# Redis
REDIS_PASSWORD=grant_redis_password # Redis auth passwordapps/api/.env (Application)
Controls the API application:
# Must match infrastructure settings
DB_URL=postgresql://grant_user:grant_password@localhost:5432/grant
REDIS_PASSWORD=grant_redis_password
# See apps/api/.env.example for all optionsService Details
PostgreSQL
Container: grant-postgres
Port: 5432
Default credentials:
- Database:
grant - User:
grant_user - Password:
grant_password
Connection string:
postgresql://grant_user:grant_password@localhost:5432/grantCommands:
# Connect via psql
docker exec -it grant-postgres psql -U grant_user -d grant
# View logs
docker-compose logs -f postgres
# Restart
docker-compose restart postgresPgAdmin
Container: grant-pgadmin
Port: 8080
Access: http://localhost:8080
Default credentials:
- Email:
admin@grant.dev - Password:
grant_password
Add Server in PgAdmin:
- Right-click "Servers" → "Register" → "Server"
- General tab: Name = "Grant"
- Connection tab:
- Host:
postgres(service name) - Port:
5432 - Database:
grant - Username:
grant_user - Password:
grant_password
- Host:
Redis
Container: grant-redis
Port: 6379
Default password: grant_redis_password
Commands:
# Connect to Redis CLI
docker exec -it grant-redis redis-cli -a grant_redis_password
# Test connection
redis-cli -h localhost -p 6379 -a grant_redis_password ping
# Response: PONG
# View cache keys
docker exec -it grant-redis redis-cli -a grant_redis_password KEYS 'grant:*'
# Monitor operations
docker exec -it grant-redis redis-cli -a grant_redis_password MONITORCommon Operations
Start Services
# All services
docker-compose up -d
# Specific service
docker-compose up -d postgres
docker-compose up -d redis
docker-compose up -d pgadminStop Services
# All services
docker-compose down
# Keep data (don't remove volumes)
docker-compose down
# Remove data (WARNING: deletes all data)
docker-compose down -vView Logs
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f postgres
docker-compose logs -f redis
# Last 100 lines
docker-compose logs --tail=100 postgresRestart Services
# All services
docker-compose restart
# Specific service
docker-compose restart postgresCheck Status
# View running containers
docker-compose ps
# View resource usage
docker stats grant-postgres grant-redisData Management
Backup Database
# Create backup
docker exec grant-postgres pg_dump -U grant_user grant > backup.sql
# With timestamp
docker exec grant-postgres pg_dump -U grant_user grant > backup-$(date +%Y%m%d-%H%M%S).sqlRestore Database
# Restore from backup
cat backup.sql | docker exec -i grant-postgres psql -U grant_user -d grant
# Or
docker exec -i grant-postgres psql -U grant_user -d grant < backup.sqlReset Database
# Stop API first
cd apps/api && pnpm run stop
# Remove and recreate
docker-compose down
docker volume rm grant_postgres_data
docker-compose up -d postgres
# Run migrations
cd apps/api && pnpm run db:migrateClear Redis Cache
# Flush all cache
docker exec -it grant-redis redis-cli -a grant_redis_password FLUSHDB
# Delete specific keys
docker exec -it grant-redis redis-cli -a grant_redis_password DEL grant:some-keyProduction Deployment
Security Considerations
Change all passwords:
bash# Generate secure passwords openssl rand -base64 32Use environment-specific
.envfiles:.env.development.env.staging.env.production
Enable TLS for Redis:
yamlredis: command: redis-server --requirepass ${REDIS_PASSWORD} --tls-port 6380 --tls-cert-file /certs/redis.crt --tls-key-file /certs/redis.keyUse external managed services:
- Managed PostgreSQL (e.g. from your cloud or database provider)
- Managed Redis (e.g. Redis Cloud, Upstash, or provider-hosted)
- Don't run databases in containers in production
Recommended Production Setup
For production, use managed services instead of Docker Compose:
# apps/api/.env (production)
DB_URL=postgresql://user:pass@your-db-host:5432/grant
REDIS_HOST=your-redis-host
REDIS_PORT=6379
REDIS_PASSWORD=your-secure-password
REDIS_ENABLE_TLS=trueTroubleshooting
Port Already in Use
Problem: Port 5432, 6379, or 8080 already in use
Solution:
# Check what's using the port
sudo lsof -i :5432
sudo lsof -i :6379
sudo lsof -i :8080
# Change port in docker-compose.yml
# PostgreSQL: "5433:5432"
# Redis: "6380:6379"
# PgAdmin: "8081:80"
# Update API .env accordingly
DB_URL=postgresql://grant_user:grant_password@localhost:5433/grant
REDIS_PORT=6380Container Won't Start
Problem: Service fails to start
Solution:
# View detailed logs
docker-compose logs postgres
# Check container status
docker-compose ps
# Remove and recreate
docker-compose down
docker-compose up -d
# Check for conflicting volumes
docker volume ls
docker volume inspect grant_postgres_dataCannot Connect to Database
Problem: API can't connect to PostgreSQL
Solutions:
Verify PostgreSQL is running:
bashdocker-compose ps postgresTest connection:
bashdocker exec -it grant-postgres psql -U grant_user -d grantCheck credentials match in both
.envfilesVerify database name matches:
bashdocker exec -it grant-postgres psql -U grant_user -l
Redis Connection Issues
Problem: API can't connect to Redis
Solutions:
Verify Redis is running:
bashdocker-compose ps redisTest connection:
bashredis-cli -h localhost -p 6379 -a grant_redis_password pingCheck password matches in both
.envfilesVerify CACHE_STRATEGY is set to
redisinapps/api/.env
Data Persistence Issues
Problem: Data disappears after restart
Solution:
# Verify volumes exist
docker volume ls | grep grant
# Check volume mounts
docker inspect grant-postgres | grep Mounts -A 10
# Don't use `docker-compose down -v` (removes volumes)
# Use `docker-compose down` insteadIntegration with API
Default Configuration
The infrastructure settings are pre-configured to work with the API defaults:
Root .env → apps/api/.env:
POSTGRES_DB=grant→DB_URL=postgresql://...@localhost:5432/grantPOSTGRES_USER=grant_user→DB_URL=postgresql://grant_user:...POSTGRES_PASSWORD=grant_password→DB_URL=postgresql://...grant_password@...REDIS_PASSWORD=grant_redis_password→REDIS_PASSWORD=grant_redis_password
No Configuration Needed
If you use the defaults, you can start services and run the API immediately:
# 1. Start infrastructure
docker-compose up -d
# 2. Copy API config (defaults already match)
cp apps/api/.env.example apps/api/.env
# 3. Run API
cd apps/api && pnpm run devRelated Documentation
- API Configuration:
apps/api/src/config/README.md - API Setup Guide:
apps/api/CONFIG_MIGRATION.md - Cache Setup:
docs/advanced-topics/caching.md - Quick Start Guide:
docs/getting-started/quick-start.md
Support
Need help?
- Check the logs:
docker-compose logs -f - Verify services:
docker-compose ps - Test connections manually (see commands above)
- Review configuration alignment
- Open an issue on GitHub
Quick Commands Reference:
# Setup
cp .env.example .env
docker-compose up -d
# Status
docker-compose ps
docker-compose logs -f
# Stop
docker-compose down
# Reset (WARNING: deletes data)
docker-compose down -v
docker-compose up -d
# Backup
docker exec grant-postgres pg_dump -U grant_user grant > backup.sql
# Access
# PostgreSQL: psql://grant_user:grant_password@localhost:5432/grant
# PgAdmin: http://localhost:8080
# Redis: redis-cli -h localhost -p 6379 -a grant_redis_password