Skip to main content

Docker Compose Profiles Guide

This guide explains how to use Docker Compose profiles and multi-file configurations for deploying the CTMS platform.

Overview

Docker Compose profiles provide a modular approach to deploying services. Instead of starting all services at once, you can selectively start groups of related services based on your needs.

Profile Structure

The CTMS platform uses the following profiles:

ProfileServicesUse Case
(none)Caddy, API Gateway, Zynexa, SublinkAlways on — start with any docker compose up
coreODM APIReport generation (adds to always-on services)
analyticsCube.dev, Cubestore, MCP ServerData analytics and AI agent
observabilityOpenObserve, OTEL CollectorLogging, metrics, and traces
linux-logsFluent BitMultiline log aggregation (Linux production only)
lakehouseLakehouse DB, Ingester, dbtData pipeline (ELT into analytics warehouse)
initctms-init, ctms-supabase-seed, ctms-user-seedOne-shot provisioning containers (run once, then exit)
allEverything (except linux-logs)Full platform deployment

Profile Naming Rationale

  • core — The ODM API service that adds report generation on top of always-on services (Caddy, API Gateway, Zynexa, Sublink).

  • analytics — Data analytics stack including Cube.dev (semantic layer for data analysis), Cubestore (pre-aggregation cache), and MCP Server (AI-powered natural language queries).

  • observability — Monitoring and logging infrastructure. Separated to allow selective deployment — not always needed in development but essential for production.

  • lakehouse — Data pipeline stack for extracting, loading, and transforming data into an analytics warehouse using dbt.

  • linux-logs — Fluent Bit for multiline Docker log aggregation. Only needed on Linux production servers; excluded from all profile.

  • init — One-shot provisioning containers. These run once to seed databases and configure Frappe, then exit. Use --profile init only during initial setup.

Startup Order (Self-Hosted)

When running the full self-hosted stack (Supabase + Frappe + CTMS), services must be started in this order:

OrderStackCommandWhy
1Supabasecd supabase && docker compose up -dDatabase and auth must be ready first
2Frappecd frappe-marley-health && docker compose up -dERP and DocTypes needed before CTMS init
3CTMS seeddocker compose --profile init run --rm ctms-supabase-seedCreates CTMS tables in Supabase
4CTMS initdocker compose --profile init up ctms-initProvisions Frappe DocTypes, RBAC, seed data
5User seeddocker compose --profile init up ctms-user-seedSeeds 4 demo users into Supabase Auth + Zynexa
6CTMS coredocker compose -f ... --profile all up -dApplication services connect to Supabase + Frappe
tip

The zynctl.sh deploy command handles this entire sequence automatically. The order above is for manual or developer deployments only.


Docker Compose Commands Explained

Basic Profile Commands

# Start core services only
docker compose --profile core up -d

# Start analytics stack
docker compose --profile analytics up -d

# Combine profiles
docker compose --profile core --profile analytics up -d

# Start everything
docker compose --profile all up -d

Multi-file Configuration

Docker Compose supports merging multiple configuration files:

docker compose -f docker-compose.yml -f docker-compose.prod.yml --profile all up -d

Flag Breakdown

FlagPurposeExample
-f <file>Specify compose file-f docker-compose.yml
--profile <name>Enable a profile--profile analytics
upCreate and start containers-
-dRun in detached mode-
configValidate and output merged config-

How Multi-file Merging Works

When multiple files are specified with -f, Docker Compose merges them in order. Later files override earlier ones:

docker compose -f docker-compose.yml -f docker-compose.prod.yml config

This command:

  1. Reads docker-compose.yml (base configuration)
  2. Reads docker-compose.prod.yml (overrides)
  3. Merges them together (prod overrides base)
  4. Outputs the final merged configuration

Use cases for multi-file:

  • docker-compose.yml - Base configuration (networks, volumes, service definitions)
  • docker-compose.prod.yml - Production overrides (direct port exposure, different images)
  • docker-compose.override.yml - Local development overrides (auto-loaded if present)

Validate Configuration

Before deploying, validate your configuration:

# Validate and see merged output
docker compose --profile all config

# Validate with production overrides
docker compose -f docker-compose.yml -f docker-compose.prod.yml --profile all config

Common Commands Reference

Starting Services

# Development (with local HTTPS)
docker compose --profile core up -d

# Production with overrides
docker compose -f docker-compose.yml -f docker-compose.prod.yml --profile all up -d

Viewing Logs

# All services
docker compose logs -f

# Specific service
docker compose logs -f zynexa

# Last 100 lines
docker compose logs --tail=100 -f

Service Management

# Stop all services
docker compose down

# Stop and remove volumes
docker compose down -v

# Restart a specific service
docker compose restart zynexa

# Check service status
docker compose ps

Updating Images

# Pull latest images (all CTMS images are pre-built via CI)
docker compose pull

# Update a service with new image
docker compose pull zynexa && docker compose up -d zynexa

Services Without Profiles (Always-On)

Services without a profile assignment will always start regardless of which profile is selected. In the CTMS stack, the following services always start when any docker compose up command is run:

  • caddy — Reverse proxy (always needed)
  • api-gateway — KrakenD API Gateway (always needed)
  • zynexa — Main CTMS web application
  • sublink — Mobile companion app

Profile Dependencies

Some profiles have implicit dependencies:

  • analytics profile: The MCP Server depends on Cube.dev for natural language queries. Both are included in the analytics profile.

  • observability profile: OTEL Collector sends data to OpenObserve. Both must run together.

Make Commands

The Makefile wraps all Docker Compose profile commands with sensible defaults. Quick examples:

make help             # Show all available commands and URLs
make up # Start core services
make up-all # Start all profiles
make down # Stop everything
make health # Check health of all services
Full Command Reference

For the complete list of Make targets — including logs, shell access, provisioning, data pipeline, and vendor stack commands — see the Platform Runbook.

Production Deployment

For production deployment on a Linux VM, use the Bundle Deployment approach — the recommended method:

# One-command deploy using zynctl
SERVER_HOST=<your-ip> ./zynctl.sh full-deploy

The bundle includes all compose files, configs, and setup scripts. zynctl.sh handles the full startup sequence (Supabase → Frappe → seed → init → CTMS core) automatically.

Troubleshooting

Profile Not Starting

Ensure you're using the correct profile name:

# ❌ Wrong
docker compose --profile ai up -d

# ✅ Correct
docker compose --profile analytics up -d

Services Missing

Check if services are assigned to profiles:

docker compose config --services
docker compose --profile all config --services

Configuration Validation Errors

# Validate before running
docker compose config

View Effective Configuration

# See exactly what Docker Compose will run
docker compose --profile core config > debug-config.yml