Problem:
- API was configured to use HTTPS in Docker with certificate at
/https/aspnetapp.pfx - Certificate didn't exist, causing startup failure
- Volume mount
~/.aspnet/https:/https:rowas trying to mount non-existent certificates
Solution:
- Changed API to use HTTP only (
http://+:8080) for Docker deployment - Removed HTTPS certificate configuration
- Removed certificate volume mount
- Updated port exposure from 5071/7109 to 8080
Rationale:
- HTTPS is unnecessary for containerized services communicating internally
- Simplifies development environment
- Production HTTPS should be handled by reverse proxy (nginx, Traefik, etc.)
- Accessing API locally:
http://localhost:5071(maps to container's 8080)
Changes:
- API Dockerfile: Changed from
EXPOSE 5071 7109toEXPOSE 8080 - docker-compose.yml: Changed from
5071:5071and7109:7109to5071:8080 - Health check: Now uses
http://localhost:8080/healthinstead of5071
Result:
- Consistent port usage across all services (API: 8080, Worker: 8080)
- External access via
http://localhost:5071for API - External access via
http://localhost:8080for Worker
Current Issues:
# docker-compose.yml line 66
SECRET_KEY: 09bc0bd1c98d956279b430beb54303f69586e0d31323d88c638ce053f77c1d79 # Exposed!
# Database credentials exposed
POSTGRES_PASSWORD: postgres
RABBITMQ_DEFAULT_PASS: guestRecommendation:
Create .env file (add to .gitignore):
# Database
POSTGRES_DB=core_ledger_db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_secure_password_here
# GlitchTip
GLITCHTIP_SECRET_KEY=your_secret_key_here
# RabbitMQ
RABBITMQ_USER=admin
RABBITMQ_PASSWORD=your_rabbitmq_password_hereUpdate docker-compose.yml:
postgres:
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
glitchtip:
environment:
SECRET_KEY: ${GLITCHTIP_SECRET_KEY}
rabbitmq:
environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}Current State:
- Only postgres has CPU/memory limits
- Other services can consume unlimited resources
Recommendation: Add resource limits to all services:
api:
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
worker:
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
rabbitmq:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
redis:
deploy:
resources:
limits:
cpus: '0.25'
memory: 256MProblem:
DATABASE_URL: postgres://postgres:postgres@core-ledger-db:5432/glitchtip_db- GlitchTip is trying to use
glitchtip_dbdatabase - This database doesn't exist (only
core_ledger_dbis created)
Solution Option 1: Create separate database
postgres:
environment:
POSTGRES_DB: core_ledger_db
POSTGRES_MULTIPLE_DATABASES: glitchtip_db # If supported by imageSolution Option 2: Use separate postgres instance for GlitchTip
glitchtip-db:
image: postgres:18
container_name: glitchtip-db
environment:
POSTGRES_DB: glitchtip_db
POSTGRES_USER: glitchtip
POSTGRES_PASSWORD: ${GLITCHTIP_DB_PASSWORD}
volumes:
- glitchtip_data:/var/lib/postgresql/dataCurrent:
volumes:
- ./logs:/var/tmp/coreledgerIssue:
- Container runs as user
1654(APP_UID) - Host
./logsdirectory might not have correct permissions - Could cause write failures
Solution: Create logs directory with correct permissions before running:
mkdir -p logs
chmod 777 logs # Or use specific UID 1654Current:
volumes:
- postgres_data:/var/lib/postgresqlShould be:
volumes:
- postgres_data:/var/lib/postgresql/dataPostgreSQL stores data in /var/lib/postgresql/data, not /var/lib/postgresql.
Current:
- Single docker-compose.yml for all environments
- BUILD_CONFIGURATION=Debug in compose file
Recommendation: Create separate compose files:
docker-compose.yml- Base configurationdocker-compose.override.yml- Development overrides (auto-loaded)docker-compose.prod.yml- Production configuration
docker-compose.override.yml (development):
version: '3.8'
services:
api:
build:
args:
BUILD_CONFIGURATION: Debug
environment:
- ASPNETCORE_ENVIRONMENT=Development
- Serilog__MinimumLevel__Default=Debug
worker:
build:
args:
BUILD_CONFIGURATION: Debug
environment:
- ASPNETCORE_ENVIRONMENT=Developmentdocker-compose.prod.yml (production):
version: '3.8'
services:
api:
build:
args:
BUILD_CONFIGURATION: Release
environment:
- ASPNETCORE_ENVIRONMENT=Production
- Serilog__MinimumLevel__Default=Information
# Remove ports exposure (use reverse proxy)- Health checks configured for all services
- Non-root user in containers (APP_UID=1654)
- Multi-stage builds for smaller images
- Minimal base images (aspnet vs sdk)
- .dockerignore file (verify exists)
- Secrets in environment variables (not hardcoded)
- Resource limits on all services
- Separate development/production configs
- Named volumes for persistent data
- Container restart policies
- Service dependencies with health conditions
- Security scanning of images
# 1. Create environment file
cp .env.template .env
# Edit .env with your secrets
# 2. Create logs directory
mkdir -p logs
chmod 777 logs
# 3. Start services
docker-compose up -d
# 4. Check health
docker-compose ps
# 5. View logs
docker-compose logs -f api
# 6. Access services
# API: http://localhost:5071
# Swagger: http://localhost:5071/swagger
# RabbitMQ: http://localhost:15672 (guest/guest)
# GlitchTip: http://localhost:8000| Service | External URL | Internal URL (from containers) |
|---|---|---|
| API | http://localhost:5071 | http://api:8080 |
| Worker | http://localhost:8080 | http://worker:8080 |
| PostgreSQL | localhost:5432 | postgres:5432 |
| RabbitMQ | localhost:5672 | rabbitmq:5672 |
| RabbitMQ UI | http://localhost:15672 | http://rabbitmq:15672 |
| Redis | localhost:6379 | redis:6379 |
| GlitchTip | http://localhost:8000 | http://glitchtip:8000 |
# Rebuild and restart
docker-compose down
docker-compose build --no-cache
docker-compose up -d
# Check API is healthy
curl http://localhost:5071/health
# Check Worker is healthy
curl http://localhost:8080/health
# View API logs
docker-compose logs -f api-
HTTPS via Reverse Proxy
- Use nginx, Traefik, or cloud load balancer for TLS termination
- Containers communicate via HTTP internally
- Example: Traefik with Let's Encrypt
-
Managed Services
- Use managed PostgreSQL (AWS RDS, Azure Database)
- Use managed Redis (ElastiCache, Azure Cache)
- Use managed message queue (AWS MQ, Azure Service Bus)
-
Secrets Management
- Use Docker Secrets (Swarm) or Kubernetes Secrets
- AWS Secrets Manager, Azure Key Vault
- Never commit secrets to git
-
Monitoring & Logging
- Centralized logging (ELK, Seq, CloudWatch)
- APM tools (Application Insights, New Relic)
- Container monitoring (Prometheus, Grafana)
-
CI/CD Pipeline
- Build images in CI pipeline
- Tag with git commit SHA or version
- Push to container registry (Docker Hub, ECR, ACR)
- Deploy using orchestration (Kubernetes, ECS, Azure Container Apps)
**/.git
**/.vs
**/.vscode
**/bin
**/obj
**/*.user
**/node_modules
**/logs
**/.env
**/.env.local
**/coverage
**/.DS_Store
# Database
POSTGRES_DB=core_ledger_db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=change_me_in_production
# GlitchTip
GLITCHTIP_SECRET_KEY=change_me_to_random_string
# RabbitMQ
RABBITMQ_USER=admin
RABBITMQ_PASSWORD=change_me_in_production
# Redis (optional authentication)
REDIS_PASSWORD=
# Auth0 (if not using mock)
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_AUDIENCE=your-api-audience