πŸ“… Week 1 β€’ Day 03

Docker Compose & Profiles

Master Docker Compose profiles to run exactly the services you need. Learn how to optimize resource usage, understand profile dependencies, and develop efficient workflows for the EmpowerNow platform.

⏱️ Duration: ~1 hour
πŸ“Š Level: Practical
🎯 Focus: Docker Operations

🎯 Learning Objectives

By the end of today's session, you will be able to:

🐳 Understanding Docker Compose Profiles

Why Profiles?

The EmpowerNow platform consists of 30+ services. Running all of them simultaneously requires significant resources and isn't necessary for most development tasks. Docker Compose profiles let you:

πŸ’‘
How Profiles Work

Services in docker-compose.yml are tagged with profile names. When you run docker compose --profile NAME up, only services with that profile (plus services with no profile) start.

πŸ“¦ Available Profiles

EmpowerNow organizes services into logical profiles. Here's what each profile includes:

🎯
Core
--profile core

Essential services for basic platform functionality. Required for most development work. This is your minimum viable setup.

Services Included
PostgreSQL Redis Neo4j IdP PDP BFF Membership IdP UI Traefik
πŸ”
Security
--profile security

Secret management and security infrastructure. Adds OpenBao (Vault) for centralized secrets and certificate management.

Services Included
OpenBao (Vault) Certificate Authority
πŸ“Š
Monitoring
--profile monitoring

Observability stack for metrics, logs, and tracing. Essential for debugging performance issues and monitoring service health.

Services Included
Prometheus Grafana Loki Jaeger Dozzle
πŸ“ˆ
Analytics
--profile analytics

Data analytics and visualization. Includes ClickHouse for event storage and Superset for dashboards.

Services Included
ClickHouse Superset Kafka Kafdrop
πŸ“
LDAP
--profile ldap

Directory services integration for enterprise identity. Use when testing LDAP authentication or sync features.

Services Included
OpenLDAP PHP LDAP Admin
πŸ”„
Data Collector
--profile datacollector

Data ingestion and synchronization services. Used for collecting data from external systems.

Services Included
datacollector dc-ui dc-alembic
πŸ› οΈ
Tools
--profile tools

Development and administration tools. Includes database GUI and log viewers for debugging and data inspection.

Services Included
pgAdmin Dozzle
πŸ”Œ
MCP
--profile mcp

MCP Gateway services for AI agent tool orchestration and external service integration.

Services Included
MCP Gateway AI Service

πŸ”§ Interactive Command Builder

πŸ”§ Profile selection is automated using your organization’s deployment procedures and approved automation.

Select the profiles you need, and we'll generate the exact command for you:

πŸ› οΈ Build Your Docker Compose Command
docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --build
πŸ”
Before running docker compose: Authenticate to Azure Container Registry (when using pre-built images)

If you run without --build, Docker pulls images from eidci.azurecr.io. Without ACR authentication, pulls fail with "authentication required".

Using --build? When you use docker-compose-build.yml with --build, services are built locally from source and tagged as :local. ACR login is not required for those overridden services.

# If you have Azure CLI installed and access to the eidci registry: az acr login --name eidci

No Azure CLI or no ACR access yet? Get credentials from Azure Portal: eidci β†’ Settings β†’ Access keys. Then run:

docker login eidci.azurecr.io # Use the Login server as registry, Username and Password from Access keys
⚠️
Before running docker compose: Grant Docker access to config_secrets

If Docker Desktop keeps restarting or cannot access secrets, run this once. Replace <YourRepoRoot> with your local clone path (e.g. D:\EmpowerNow or E:\Source\Repos\EmpowerNow on Windows; /Users/you/EmpowerNow on macOS/Linux):

# Run in PowerShell as Administrator icacls "<YourRepoRoot>\ServiceConfigs\Deployment\config_secrets" /grant Everyone:F

Path must end with ...\ServiceConfigs\Deployment\config_secrets (Windows) or .../ServiceConfigs/Deployment/config_secrets (macOS/Linux).

macOS/Linux: Ensure config_secrets is readable (e.g. chmod -R u+r config_secrets from ServiceConfigs/Deployment).

πŸ“„
Before running docker compose: Create idp-bootstrap-secrets.env

The compose file references env/services/idp-bootstrap-secrets.env for the IdP bootstrap init container. If this file is missing or empty, create it under ServiceConfigs/Deployment/env/services/:

# IdP Bootstrap Secrets # Used by idp-bootstrap-secrets init container to set admin password # and service-client secret in the IdP database after migrations. IDP_ADMIN_PASSWORD=<your-secure-password> IDP_SERVICE_CLIENT_SECRET=<your-secure-secret>

Generate strong values: openssl rand -base64 24 for password, openssl rand -base64 32 for secret. If both are unset, the init container skips (stack still comes up, but BFF DCR may fail). Do not commit real values to git.

πŸ”§ DCR script and stack restart are automated using your organization’s deployment procedures and approved automation.
🚨
First-Time Setup: BFF Registration Required!

On first startup, the BFF needs to register with IdP. If BFF keeps restarting after docker compose up, run this script from ServiceConfigs\Deployment:

# Run from ServiceConfigs\Deployment directory .\scripts\create-idp-admin-jwt-secret.ps1 # Then restart services docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --build

This generates a JWT admin token for BFF's Dynamic Client Registration (DCR) with IdP. Only needed once!

πŸ“‹ Common Usage Patterns

Pattern 1: Minimal Development

πŸ”§ Starting the stack is automated using your organization’s deployment procedures and approved automation.

For working on a single service with minimal dependencies. Always run from ServiceConfigs/Deployment (do not run compose from CRUDService). On Linux use exact casing: serviceconfigs/Deployment.

PowerShell
# Start core services (from ServiceConfigs/Deployment) cd <YourRepoRoot>/ServiceConfigs/Deployment docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --build
πŸ”§ Service verification is automated using your organization’s deployment procedures and approved automation.
πŸ§ͺ Try It: Verify Core Services Started

After running docker compose with core profile, verify services are healthy:

Pattern 2: Full Development Stack

For comprehensive development with monitoring and security:

PowerShell
# Full development stack (from ServiceConfigs/Deployment) docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core --profile security --profile monitoring up -d --build

Pattern 3: Everything

For integration testing or production-like environment:

PowerShell
# All profiles - requires significant resources! (from ServiceConfigs/Deployment) docker compose -f docker-compose.yml -f docker-compose-build.yml \ --profile core \ --profile security \ --profile monitoring \ --profile analytics \ --profile ldap \ --profile datacollector \ up -d --build
⚠️
Resource Warning

Running all profiles requires at least 16GB RAM allocated to Docker. Monitor your system resources and adjust profiles based on your hardware capabilities.

πŸ’Ύ Resource Estimation

Understanding resource usage helps you choose appropriate profiles:

Estimated Resource Usage by Profile Combination

~4GB
Core Only
Essential services
~7GB
Core + Monitoring
With observability
~10GB
Full Dev Stack
Core + Security + Monitoring
~14GB
All Profiles
Complete platform

πŸ“ Deployment File Structure

Understanding the file structure helps you customize configurations:

ServiceConfigs/Deployment Directory Structure
πŸ“ Deployment/
πŸ“„ docker-compose.yml ← Main compose file (images)
πŸ“„ docker-compose-build.yml ← Build from source
πŸ“„ .env ← Root environment variables
πŸ“ env/
πŸ“ services/ ← Service-specific env files
πŸ“„ idp.env
πŸ“„ pdp.env
πŸ“„ bff.env
πŸ“ config_secrets/ ← Docker secrets
πŸ“ scripts/ ← Helper scripts

πŸ”¨ Building from Source

When you need to test local changes, use the build compose file:

PowerShell
# Build all services from source docker compose -f docker-compose.yml -f docker-compose-build.yml \ --profile core up -d --build # Build specific service only docker compose -f docker-compose.yml -f docker-compose-build.yml \ --profile core up -d --build --no-deps idp # Force rebuild without cache docker compose -f docker-compose.yml -f docker-compose-build.yml \ --profile core build --no-cache idp
πŸ’œ
Development Workflow

Use --no-deps when rebuilding a single service to avoid restarting dependent services. Use --build to ensure Docker picks up your latest changes.

πŸš€ First Run: BFF DCR Setup

The first time you start the platform, you need to configure the BFF's Dynamic Client Registration (DCR):

PowerShell
❯ cd <YourRepoRoot>/ServiceConfigs/Deployment

Replace <YourRepoRoot> with your project root (e.g. EmpowerNow or full path). Windows: use backslashes.

❯ docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --build
# BFF will start and crash initially - this is expected!

❯ ./scripts/create-idp-admin-jwt-secret.ps1
βœ“ Created admin JWT secret for BFF DCR

❯ docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --build
# BFF will now start successfully
⚠️
Important: First Run Only

This DCR setup is only needed on the first run. The secret is persisted and reused on subsequent starts. If you reset volumes, you'll need to run this again.

πŸ—„οΈ Using pgAdmin (Tools Profile)

pgAdmin is a powerful PostgreSQL administration tool included in the tools profile. It provides a web-based GUI for inspecting databases, running queries, and managing schemas.

Starting pgAdmin

PowerShell
# Start core services with tools profile docker compose --profile core --profile tools up -d # Or add tools to existing running services docker compose --profile tools up -d

Accessing pgAdmin

🌐
Access URLs

Via Traefik: https://pgadmin.self.empowernow.ai
Direct Port: http://localhost:5050

Default Credentials

pgAdmin Login
Email: admin@empowernow.ai Password: EmpowerNow2024!

Configuring Database Connection

After logging in, you need to add a server connection to access the PostgreSQL database:

  1. Right-click Servers in the left panel β†’ Register β†’ Server...
  2. On the General tab:
    • Name: EmpowerNow DB (any friendly name)
  3. On the Connection tab:
    • Host name/address: db (Docker service name)
    • Port: 5432
    • Maintenance database: postgres
    • Username: postgres
    • Password: empowernow (from Docker secrets)
  4. Check Save password and click Save
πŸ’œ
Docker Networking

Use db (the Docker service name) as the hostname, not localhost. pgAdmin runs inside Docker and needs to connect to the database via Docker's internal network.

Key Databases

Once connected, you'll see these main databases:

PostgreSQL Databases
idp_db β†’ Identity Provider (users, clients, tokens) pdp_db β†’ Policy Decision Point (policies, scopes) crud_db β†’ CrudService (workflows, schemas, data) membership_db β†’ Membership service (roles, assignments)

Useful pgAdmin Tasks

Query IdP Users

SQL
-- List all users SELECT username, email, is_active, created_at FROM idp.users ORDER BY created_at DESC; -- Find a specific user SELECT * FROM idp.users WHERE username = 'test';

Query OAuth Clients

SQL
-- List all registered OAuth clients SELECT client_id, client_name, client_type, grant_types, scopes FROM idp.oauth_clients ORDER BY created_at DESC; -- Check client configuration details SELECT c.client_id, c.client_name, e.config FROM idp.oauth_clients c LEFT JOIN idp.oauth_client_ext e ON c.client_id = e.client_id;
βœ…
Best Practice: Read-Only Queries

Use pgAdmin primarily for inspection and debugging. Avoid manual INSERT/UPDATE/DELETE on production dataβ€”use the service APIs instead for data modifications.

πŸ“– Essential Commands Reference

Starting Services

Commands
# Start with profile(s) - from ServiceConfigs/Deployment docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --build # Start and follow logs docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up # Start specific service docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d idp

Stopping Services

Commands
# Stop all services (preserves data) docker compose --profile core down # Stop and remove volumes (DESTRUCTIVE!) docker compose --profile core down -v # Stop specific service docker compose stop idp

Viewing Logs

Commands
# All logs docker compose logs # Follow logs in real-time docker compose logs -f # Specific service logs docker compose logs -f idp # Last 100 lines docker compose logs --tail 100 idp

Service Status

Commands
# List running services docker compose ps # Detailed status docker compose ps -a # Resource usage docker stats

πŸ› οΈ Hands-on Exercises

Exercise 1: Start Core Services

  1. Navigate to ServiceConfigs/Deployment
  2. Start the core profile: docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --build
  3. Run the DCR script if first time
  4. Verify all services are healthy: docker compose ps

Exercise 2: Add Monitoring

  1. Add the monitoring profile: docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core --profile monitoring up -d --build
  2. Access Grafana at http://grafana.self.empowernow.ai
  3. Check Prometheus targets at http://prometheus.self.empowernow.ai/targets

Exercise 3: Resource Monitoring

  1. Run docker stats in a terminal
  2. Identify which services use the most memory
  3. Note CPU usage patterns

Exercise 4: Explore with pgAdmin

  1. Start the tools profile: docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core --profile tools up -d --build
  2. Access pgAdmin at http://localhost:5050
  3. Login with admin@empowernow.ai / EmpowerNow2024!
  4. Register a new server connection to the db container
  5. Navigate to idp_db β†’ Schemas β†’ idp β†’ Tables
  6. Right-click the users table β†’ View/Edit Data β†’ All Rows
  7. Try running this query in the Query Tool: SELECT * FROM idp.oauth_clients;

πŸ“‹ Day 3 Summary

βœ…
Key Achievements

You now understand how to efficiently manage the EmpowerNow Docker environment using profiles, optimize resource usage, and build services from source for development.

Key Takeaways:

Tomorrow's Preview:

Day 4 covers Configuration & Secrets Management - understanding how services are configured, environment files, and OpenBao vault integration.