Overview
Docker Compose deployment provides a production-like environment with all services containerized and orchestrated. This is the recommended approach for testing, staging, and small-to-medium production deployments.Architecture
The Docker Compose setup includes six services:postgres
PostgreSQL 16 with pgvector extension for relational data and vector storage
redis
Redis 7 for session caching and asynchronous job processing (Streams)
minio
S3-compatible object storage for resumes, documents, and generated reports
createbuckets
Init container that auto-creates storage buckets before app startup
app
Spring Boot backend with AI integration and business logic
frontend
React SPA served by Nginx with API reverse proxy
Prerequisites
- Docker: 20.10+ (Install Docker)
- Docker Compose: 2.0+ (included with Docker Desktop)
- Alibaba Cloud DashScope API Key: Get API Key
Quick Start
Service Configuration
Dependency Management
Services start in the correct order using health checks:docker-compose.yml
Why use health checks instead of just depends_on?
Why use health checks instead of just depends_on?
Without health checks,
depends_on only waits for the container to start, not be ready. This causes race conditions:- Backend tries to connect before PostgreSQL accepts connections → crash
- Backend uploads file before bucket exists → 404 error
Health Check Configuration
PostgreSQL Health Check
PostgreSQL Health Check
- What it does: Executes
pg_isreadyto verify PostgreSQL accepts connections - Why: Prevents “connection refused” errors during backend startup
- Timing: Checked every 5s, max 25s wait (5 retries × 5s)
Redis Health Check
Redis Health Check
- What it does: Sends
PINGcommand, expectsPONGresponse - Why: Ensures Redis is ready for Redisson connection
- Timing: Checked every 5s, max 15s wait
MinIO Health Check
MinIO Health Check
- What it does: Calls MinIO’s built-in health endpoint
- Why: Ensures S3 API is ready before bucket creation
- Timing: Checked every 5s, max 15s wait
Init Container Pattern
Thecreatebuckets service implements the Init Container pattern:
docker-compose.yml
Volume Management
Data Persistence
Named volumes ensure data survives container restarts:docker-compose.yml
Clean Up Volumes
Networking
Internal DNS Resolution
Docker Compose creates a default bridge network where services communicate using service names as hostnames:Why use service names instead of localhost?
Why use service names instead of localhost?
In Docker, each container has its own network namespace:
localhostinside theappcontainer refers to the app container itself- Service names (e.g.,
postgres) resolve to the container’s internal IP via Docker’s DNS
Port Mapping
| Service | Internal Port | External Port | Access From | |----------|---------------|---------------|--------------------|| | frontend | 80 | 80 | Host browser | | app | 8080 | 8080 | Host tools (curl) | | postgres | 5432 | 5432 | Host DB clients | | redis | 6379 | 6379 | Host redis-cli | | minio | 9000, 9001 | 9000, 9001 | Host browser |Multi-Stage Builds
Both backend and frontend use multi-stage Dockerfiles to minimize image size:Backend Build Stages
Frontend Build Stages
Operations
Common Commands
Start Services
Start Services
Stop Services
Stop Services
View Logs
View Logs
Restart Services
Restart Services
Execute Commands Inside Containers
Execute Commands Inside Containers
View Resource Usage
View Resource Usage
Updating the Application
Troubleshooting
Service Won't Start - 'unhealthy' Status
Service Won't Start - 'unhealthy' Status
Symptom: Common Causes:
docker compose ps shows service as unhealthyDebug Steps:- PostgreSQL: Database initialization taking longer than health check timeout
- Redis: Port conflict with host Redis instance
- MinIO: Insufficient disk space in Docker volume
Backend Crashes on Startup
Backend Crashes on Startup
Symptom: Solutions:
interview-app container exits immediatelyDebug Steps:- Verify environment variables are set in
.env - Check all dependencies are healthy:
- Restart with clean state:
'Port already in use' Error
'Port already in use' Error
Symptom:
Error starting userland proxy: listen tcp4 0.0.0.0:5432: bind: address already in useSolutions:- Find conflicting process:
- Stop conflicting service:
High Memory Usage
High Memory Usage
Symptom: Docker Desktop shows high RAM usage or system slowdownOptimize:
- Set JVM heap limits for backend:
docker-compose.yml
- Limit container resources:
- Adjust Redis maxmemory:
Cannot Access Frontend at localhost
Cannot Access Frontend at localhost
Symptom: Browser shows “Connection refused” or timeoutDebug Steps:Common Issues:
- Port 80 requires admin privileges on some systems → Change to 8000:80
- Firewall blocking localhost:80 → Check firewall rules
- Build failed silently → Check
docker compose logs frontendfor errors
Next Steps
Production Deployment
Secure and optimize for production
Configuration Guide
Customize environment variables
Backup & Recovery
Database backup strategies
Monitoring Setup
Add observability stack
