7.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Kompose is a Bash-based orchestration tool for managing multiple Docker Compose stacks from a single repository. Each subdirectory represents a "stack" (a Docker Compose application), and the central kompose.sh script provides unified commands for lifecycle management, database operations, and custom hooks.
Architecture
Core Components
kompose.sh: Main orchestration script (bash) that manages all stacks- Stack Directories: Each directory (
auth/,blog/,track/, etc.) represents a self-contained Docker Compose stack - Environment Management: Two-tier configuration system:
- Root
.env: Non-sensitive configuration and stack-scoped variables secrets.env: Sensitive data (passwords, tokens) - generated fromsecrets.env.template
- Root
- Hooks System: Per-stack lifecycle hooks in
<stack>/hooks.sh
Key Design Patterns
- Stack-Scoped Variables: Configuration uses
{STACK_NAME}_{VARIABLE}pattern (e.g.,TRACK_TRAEFIK_HOST,AUTH_DB_NAME) - Shared Variables: Common settings like
DB_USER,DB_HOST,NETWORK_NAMEshared across all stacks - Hook-Based Extensibility: Each stack can define custom pre/post hooks for Docker Compose commands and database operations
- Centralized Network: All stacks connect to a shared Docker network (
komposeby default)
Stack Structure
Each stack directory contains:
compose.yamlordocker-compose.yaml: Docker Compose configuration.env: Stack-specific variables (typically justCOMPOSE_PROJECT_NAME)hooks.sh(optional): Custom lifecycle hooks- Database dumps:
{DB_NAME}_{timestamp}.sqlfiles
Monorepo Stacks
Some stacks are complete applications with their own build systems:
news/: Turborepo monorepo with Next.js apps (pnpm workspace)docs/: Nuxt.js documentation site (pnpm)
Common Commands
Core Operations
# Start all stacks
./kompose.sh "*" up -d
# Start specific stack(s)
./kompose.sh auth up -d
./kompose.sh "auth,blog,data" up -d
# Stop stack(s)
./kompose.sh auth down
./kompose.sh "*" down
# View logs
./kompose.sh auth logs -f
./kompose.sh "*" logs --tail=100
# Check status
./kompose.sh --list
./kompose.sh "*" ps
# Restart services
./kompose.sh auth restart
# Dry-run mode (preview without executing)
./kompose.sh --dry-run "*" up -d
Database Operations
# Export database dump(s)
./kompose.sh auth db:export
./kompose.sh "*" db:export
# Import latest dump (WARNING: drops & recreates database)
./kompose.sh auth db:import
# Import specific dump file
./kompose.sh auth db:import auth/keycloak_20251007_080554.sql
# Clean up old dumps (keeps only latest)
./kompose.sh "*" db:cleanup
Environment Overrides
# Override variables from CLI
./kompose.sh -e DB_HOST=localhost -e DB_PORT=5433 news up -d
# Override network name
./kompose.sh --network custom_network "*" up -d
Secret Management
# Generate secrets from template (creates secrets.env)
./kompose.sh --generate-secrets
Development Workflows
Monorepo Stacks (news, docs)
# News stack (Turborepo)
cd news
pnpm install
pnpm dev # Start all apps in dev mode
pnpm build # Build all apps
pnpm lint # Lint all apps
# Docs stack (Nuxt)
cd docs
pnpm install
pnpm dev # Start dev server
pnpm build # Build for production
pnpm generate # Generate static site
Testing kompose.sh Changes
# Check syntax
bash -n kompose.sh
# Use shellcheck for best practices
shellcheck kompose.sh
# Test with dry-run
./kompose.sh --dry-run auth up -d
Hooks System
Stacks can define custom hooks in <stack>/hooks.sh for lifecycle management.
Available Hooks
Database Hooks:
hook_pre_db_export: Before database exporthook_post_db_export: After database export (receives dump file path)hook_pre_db_import: Before database import (receives dump file path)hook_post_db_import: After database import
Docker Compose Command Hooks:
hook_pre_<command>: Before docker compose command (up, down, start, stop, restart, build, pull, logs, etc.)hook_post_<command>: After docker compose command (only runs on success)
Hook Example
The sexy/ stack uses hooks to manage Directus schema snapshots:
hook_pre_db_export() {
# Export Directus schema before database export
docker exec "${COMPOSE_PROJECT_NAME}_api" npx directus schema snapshot
}
hook_post_db_import() {
# Restart Directus after database import
docker restart "${COMPOSE_PROJECT_NAME}_api"
}
Hook Reference
- Hooks receive command arguments as parameters:
$@ - Return
0for success,1for failure - Post-hooks only execute if the main command succeeds
- Available environment variables:
$SCRIPT_DIR,$stack, all.envvariables - Template available at
hooks.sh.template
Environment Variables
Configuration Structure
-
Root
.env: Stack-scoped configuration (committed to git)- Pattern:
{STACK}_{VARIABLE}(e.g.,AUTH_TRAEFIK_HOST) - Shared variables:
DB_USER,DB_HOST,NETWORK_NAME, etc.
- Pattern:
-
secrets.env: Sensitive data (NOT committed to git)- Generated from
secrets.env.templateusing--generate-secrets - Pattern:
{STACK}_{SECRET}(e.g.,AUTH_KC_ADMIN_PASSWORD)
- Generated from
-
Stack
.env: Minimal stack-specific overrides- Typically only contains
COMPOSE_PROJECT_NAME
- Typically only contains
Secret Generation Patterns
The --generate-secrets command generates different secret types:
*_PASSWORD: 32-char alphanumeric password*_SECRET,*_ENCRYPTION_KEY: 64-char hex (32 bytes)*_TOKEN: 40-char alphanumeric token*_HASH: 64-char hex hash- Default: 32-char alphanumeric
Important Notes
Security
secrets.envis in.gitignoreand should NEVER be committed- Use
secrets.env.templateas a reference for required secrets - Stack-scoped variables prevent conflicts between stacks
Database Operations
- Database imports are destructive - they drop and recreate the database
- Always backup before running
db:import - Database dumps are saved as
{DB_NAME}_{timestamp}.sqlin stack directories - Only PostgreSQL databases are currently supported
Network Configuration
- All stacks use a shared Docker network (default:
kompose) - Network must be created before starting stacks:
docker network create kompose - Override network with
--networkflag orNETWORK_NAMEin.env
Traefik Integration
- Services can be exposed via Traefik reverse proxy
- Control per-stack:
{STACK}_TRAEFIK_ENABLED=true/false - Host configuration:
{STACK}_TRAEFIK_HOST=subdomain.example.com
Migration Guide
Recent changes introduced stack-scoped variables and centralized secrets management. See MIGRATION_GUIDE.md for detailed migration steps from the old configuration format.
Code Style Guidelines
Bash Script Conventions (kompose.sh)
- Constants:
UPPER_CASEwithreadonly - Local variables:
lowercase_with_underscores - Functions:
function_name()with descriptive names - Error handling: Use
set -euo pipefail - Logging: Use provided functions (
log_info,log_error,log_success,log_warning) - Indentation: 4 spaces
- Return codes:
0for success,1for failure - ShellCheck: Code should pass
shellchecklinting
Hook Development
- Return
0for success, even for non-critical failures - Use indented output:
echo " Message" - Check container status before
docker execcommands - Test with
--dry-runbefore executing - Add timeouts for long-running operations
- Document hooks with comments
Documentation Location
Full documentation is available in docs/ (Nuxt site). Key documents:
CONTRIBUTING.md: Contribution guidelinesHOOKS_QUICKREF.md: Quick reference for hooks systemMIGRATION_GUIDE.md: Configuration migration guidehooks.sh.template: Template for creating stack hooks