- Quick local development and testing
- Lower resource consumption compared to Kubernetes
- Simpler debugging with direct container access
- CI/CD pipelines and integration tests
Prerequisites
- Environment setup complete
- Docker Desktop or Docker Engine running
.envfile copied from.env.example
Quick Start
Start all services
From the project root, run:
The first run will build all Docker images, which may take 5-10 minutes depending on your machine.
Verify services are running
Check that all containers are healthy:You should see all services in the “running” or “healthy” state.
Service Architecture
The Docker Compose stack includes the following services:Service Details
Infrastructure Services
Traefik
Reverse proxy and API gateway- Port: 30081 (HTTP)
- Purpose: Routes requests to backend services based on path
- Features: CORS middleware, rate limiting, request retry
- Health check:
http://localhost:30081/ping
PostgreSQL
Database server- Port: 5432
- Credentials:
devuser/devpass(from.env) - Databases: Automatically creates separate databases for each service
greeter_dbcaller_dbgateway_dblang_dbauth_db
Go Microservices (connect-go)
Greeter Service
- Internal port: 8080
- API path:
/greeter.v1.GreeterService - Protocol: gRPC (connect-go)
- Dependencies: Caller service, PostgreSQL
- Environment variables:
CALLER_BASE_URL=http://caller:8081EXTERNAL_API_URL=https://httpbin.org/getDATABASE_URL=postgresql://devuser:devpass@postgres:5432/greeter_db
Caller Service
- Internal port: 8081
- Protocol: gRPC (connect-go)
- Dependencies: PostgreSQL
- Environment variables:
DATABASE_URL=postgresql://devuser:devpass@postgres:5432/caller_db
Gateway Service
- Internal port: 8082
- API path:
/gateway.v1.GatewayService - Protocol: gRPC (connect-go)
- Dependencies: Custom Lang Service, PostgreSQL
- Environment variables:
CUSTOM_LANG_BASE_URL=http://custom-lang-service:3000DATABASE_URL=postgresql://devuser:devpass@postgres:5432/gateway_db
Node.js Microservices (Express)
Auth Service
- Internal port: 8090
- API path:
/auth - Protocol: HTTP/REST
- Purpose: JWT authentication (login, signup, token validation)
- Environment variables:
JWT_SECRET=dev-secretDATABASE_URL=postgresql://devuser:devpass@postgres:5432/auth_db
Custom Lang Service
- Internal port: 3000
- Protocol: HTTP/REST
- Purpose: Custom language processing service
- Environment variables:
DATABASE_URL=postgresql://devuser:devpass@postgres:5432/lang_db
Frontend
React Application
- Internal port: 80 (nginx)
- Build-time args:
VITE_API_BASE_URL=http://localhost:30081
- Technology: React 19 + TypeScript + Vite
- API Client: connect-query (connect-rpc + TanStack Query)
Port Reference
| Service | Internal Port | External Port | Access URL |
|---|---|---|---|
| Traefik | 80 | 30081 | http://localhost:30081 |
| PostgreSQL | 5432 | 5432 | localhost:5432 |
| Greeter | 8080 | - | Via Traefik |
| Caller | 8081 | - | Internal only |
| Gateway | 8082 | - | Via Traefik |
| Auth | 8090 | - | Via Traefik |
| Custom Lang | 3000 | - | Internal only |
| Frontend | 80 | - | Via Traefik |
Only Traefik and PostgreSQL expose ports to the host. All other services communicate through Docker’s internal network.
Common Operations
Start services in background
View logs
Restart a service
Stop services
Execute commands in containers
Traefik Routing
Traefik routes requests based on path prefixes:API Services (gRPC)
Connect-go services use the pattern/package.version.ServiceName/Method:
Auth Service (REST)
Frontend
All other paths route to the React frontend:Middleware Configuration
Traefik applies the following middleware automatically:| Middleware | Services | Purpose |
|---|---|---|
cors@file | All | CORS headers for browser requests |
auth@file | greeter, gateway | JWT token validation |
rate-limit@file | All | Rate limiting (configurable in deploy/traefik/dynamic/) |
retry@file | greeter | Automatic retry on failure |
Debugging
Check service health
Test gRPC endpoints directly
If you have the devenv shell active, you can usegrpcurl:
Inspect database
Reset everything
If you encounter issues, try a clean restart:Development Workflow
For faster iteration on the frontend, use the local development server instead of rebuilding the Docker container.
Troubleshooting
Service won’t start
Check dependencies:Port already in use
If port 30081 or 5432 is already in use:Database connection errors
Verify PostgreSQL is healthy and accepting connections:Traefik routing issues
Check Traefik configuration:Next Steps
Kubernetes + Tilt
Advanced local development with full observability
Frontend Development
Run frontend with hot reload