Docker Compose Configuration
The repository includes adocker-compose.yml file with two services:
- postgres: PostgreSQL 16 database
- api: rs-tunnel API server
Service Configuration
PostgreSQL Service
PostgreSQL 16 database using the official Alpine-based image.Key configuration:
- Image:
postgres:16-alpine(lightweight, production-ready) - Restart policy:
unless-stopped(auto-restart on failure) - Port mapping: Host
23432→ Container5432 - Data persistence:
pgdatanamed volume
Port Mapping
The database is exposed on host port 23432 (not the default 5432) to avoid conflicts with existing PostgreSQL installations.
- From host machine:
postgres://postgres:postgres@localhost:23432/rs_tunnel - From API container:
postgres://postgres:postgres@postgres:5432/rs_tunnel
Volume Mount
pgdata named volume. This ensures data survives container restarts.
Environment Variables
Database name to create on first startup.
PostgreSQL superuser name.
PostgreSQL superuser password.
API Service
rs-tunnel API server built from
apps/api/Dockerfile.Key configuration:- Build context: Repository root (enables monorepo builds)
- Depends on:
postgres(waits for database to start) - Port: Exposes 8080 internally
Service Dependencies
The API handles database connection retries automatically. If migrations fail due to database not being ready, wait a few seconds and retry.
Internal Networking
postgres as the hostname. Docker Compose creates an internal network where services resolve each other by name.
From outside Docker (like the CLI during development), use
localhost:23432.Running with Docker Compose
Development Setup
Create environment file
Create a Edit
.env file in the repository root:.env with your configuration (see Environment Variables).Start PostgreSQL only
For local development, run only the database:This allows you to run the API directly with
pnpm for faster iteration.Production Deployment
Build and start all services
--env-file: Use production environment-d: Run in detached mode--build: Rebuild API image
Health Checks
The Docker setup doesn’t include explicit health checks indocker-compose.yml, but you can verify service health:
PostgreSQL Health
API Health
Check if the API is responding:The API exposes a health endpoint (if implemented). Alternatively, check the logs for “Server listening on port 8080”.
Volume Management
Inspect Volume
Backup Database
Restore Database
Common Docker Commands
Troubleshooting
Port 23432 already in use
Port 23432 already in use
Cause: Another service is using port 23432.Solution:
- Change the host port in
docker-compose.yml: - Update
DATABASE_URLto use new port - Restart services:
API can't connect to database
API can't connect to database
Cause: Database not ready or connection string incorrect.Solution:
- Check PostgreSQL is running:
- Verify
DATABASE_URLuses service namepostgres(notlocalhost): - Check PostgreSQL logs:
Build fails: 'Cannot find module @ripeseed/shared'
Build fails: 'Cannot find module @ripeseed/shared'
Data lost after restart
Data lost after restart
Cause: Volume was removed or not properly mounted.Solution:
- Don’t use
docker compose down -vunless you want to delete data - Verify volume exists:
- Use regular stop/start:
Production Considerations
- Use managed PostgreSQL: AWS RDS, Google Cloud SQL, or Azure Database for PostgreSQL
- Change default credentials: Never use
postgres:postgresin production - Enable SSL: Add
?sslmode=requiretoDATABASE_URL - Add health checks: Implement proper health check endpoints
- Use secrets management: HashiCorp Vault, AWS Secrets Manager, etc.
- Set resource limits: Add memory/CPU limits to service definitions
- Enable logging: Use logging drivers for centralized log collection
- Add monitoring: Prometheus, Grafana, or cloud-native monitoring
Example Production docker-compose.yml
docker-compose.production.yml
Next Steps
Database Migration
Run Drizzle ORM migrations to initialize the schema
Environment Variables
Complete environment variable reference

