# ============================================================================= # TrakBridge Docker Compose Configuration # ============================================================================= # # Usage: # docker-compose up # App only (requires external DB or SQLite) # docker-compose --profile postgres up # App + PostgreSQL # docker-compose --profile mysql up # App + MySQL # docker-compose --profile nginx up # App + Nginx reverse proxy # docker-compose --profile postgres --profile nginx up # Full stack (single worker deployment) # # Configuration: # Edit the 'x-environment' section below to customize your deployment # # Persistent Configuration: # The application supports persistent configuration through the ./config volume mount. # Default configuration files are automatically installed on first run. # Set TRAKBRIDGE_CONFIG_UPDATE_MODE to control how configs are updated: # - "preserve": Keep existing configs (default) # - "overwrite": Replace with container defaults # - "merge": Smart merge (future feature) # # Single Worker Deployment: # TrakBridge now operates as a single worker deployment optimized for Hypercorn. # All configuration changes apply immediately without coordination delays. # # ============================================================================= # ============================================================================= # CONFIGURATION SECTION - Edit these values for your deployment # ============================================================================= x-environment: &common-environment # Application Settings APP_VERSION: "latest" FLASK_ENV: "production" FLASK_APP: "app.py" APP_PORT: "5000" USER_ID: "1000" # Change if needed for filesystem permissions GROUP_ID: "1000" # Change if needed for filesystem permissions # Configuration Management TRAKBRIDGE_CONFIG_DIR: "/app/external_config" TRAKBRIDGE_CONFIG_AUTO_INSTALL: "true" TRAKBRIDGE_CONFIG_UPDATE_MODE: "preserve" # Database Configuration - PostgreSQL (default) DB_TYPE: "postgresql" DB_HOST: "postgres" DB_PORT: "5432" DB_NAME: "trakbridge" DB_USER: "trakbridge" # Database Configuration - MySQL (alternative - comment out PostgreSQL above if using) # DB_TYPE: "mysql" # DB_HOST: "mysql" # DB_PORT: "3306" # DB_NAME: "trakbridge" # DB_USER: "trakbridge" # Database Configuration - SQLite (alternative - comment out PostgreSQL above if using) # DB_TYPE: "sqlite" # Application Performance DEBUG: "false" LOG_LEVEL: "INFO" MAX_WORKER_THREADS: "4" DEFAULT_POLL_INTERVAL: "120" HTTP_TIMEOUT: "30" # Security Configuration PROXY_TRUSTED: "false" # Set to "true" if behind reverse proxy (nginx, load balancer) TRUSTED_PROXY_COUNT: "0" # Number of proxies in chain (e.g., "1" for nginx) FORCE_HTTPS: "false" # Force HTTPS redirect (disable with "false" for internal deployments only) # Hypercorn Settings - single worker optimal for TrakBridge architecture HYPERCORN_KEEP_ALIVE: "5" HYPERCORN_MAX_REQUESTS: "1000" HYPERCORN_MAX_REQUESTS_JITTER: "100" # Authentication Configuration # LDAP Settings (set LDAP_ENABLED to "true" and configure for your environment) LDAP_ENABLED: "false" LDAP_SERVER: "ldap://your-ad-server.company.com" # Update for your LDAP server LDAP_PORT: "389" LDAP_USE_SSL: "false" LDAP_USE_TLS: "true" LDAP_VALIDATE_CERT: "true" LDAP_BIND_DN: "CN=trakbridge,OU=Service Accounts,DC=company,DC=com" # Update for your domain LDAP_USER_SEARCH_BASE: "OU=Users,DC=company,DC=com" # Update for your domain LDAP_USER_SEARCH_FILTER: "(sAMAccountName={username})" LDAP_GROUP_SEARCH_BASE: "OU=Groups,DC=company,DC=com" # Update for your domain LDAP_GROUP_SEARCH_FILTER: "(member={user_dn})" LDAP_ADMIN_GROUP: "CN=TrakBridge-Admins,OU=Groups,DC=company,DC=com" # Update group names LDAP_OPERATOR_GROUP: "CN=TrakBridge-Operators,OU=Groups,DC=company,DC=com" LDAP_USER_GROUP: "CN=TrakBridge-Users,OU=Groups,DC=company,DC=com" LDAP_DEFAULT_ROLE: "user" LDAP_CONNECTION_TIMEOUT: "10" LDAP_RESPONSE_TIMEOUT: "30" # Container Management & Startup Optimization CONTAINER_MANAGED: "true" SCHEMA_VALIDATION_MODE: "fast" MIGRATION_TIMEOUT: "30" # OIDC/SSO Settings (set OIDC_ENABLED to "true" and configure for your identity provider) OIDC_ENABLED: "false" OIDC_ISSUER: "https://your-identity-provider.com" # Update for your OIDC provider OIDC_CLIENT_ID: "trakbridge-client" # Update with your client ID OIDC_REDIRECT_URI: "https://trakbridge.company.com/auth/oidc/callback" # Update for your domain OIDC_VERIFY_SIGNATURE: "true" OIDC_VERIFY_AUDIENCE: "true" OIDC_VERIFY_ISSUER: "true" OIDC_ADMIN_GROUP: "trakbridge-admins" # Update role mappings for your provider OIDC_OPERATOR_GROUP: "trakbridge-operators" OIDC_USER_GROUP: "trakbridge-users" OIDC_DEFAULT_ROLE: "user" # Local Authentication (always available as fallback) LOCAL_AUTH_ENABLED: "true" PASSWORD_MIN_LENGTH: "12" PASSWORD_REQUIRE_UPPERCASE: "true" PASSWORD_REQUIRE_LOWERCASE: "true" PASSWORD_REQUIRE_NUMBERS: "true" PASSWORD_REQUIRE_SPECIAL: "true" PASSWORD_MAX_AGE_DAYS: "90" # Session Configuration SESSION_LIFETIME_HOURS: "8" SESSION_CLEANUP_INTERVAL: "60" SESSION_SECURE_COOKIES: "true" SESSION_COOKIE_DOMAIN: "" # Leave blank for auto-detection SESSION_COOKIE_PATH: "/" # Secret file paths - customize if needed x-secrets: &common-secrets DB_PASSWORD_FILE: "./secrets/db_password" SECRET_KEY_FILE: "./secrets/secret_key" TB_MASTER_KEY_FILE: "./secrets/tb_master_key" LDAP_BIND_PASSWORD_FILE: "./secrets/ldap_bind_password" OIDC_CLIENT_SECRET_FILE: "./secrets/oidc_client_secret" services: # ============================================================================= # TrakBridge Application # ============================================================================= trakbridge: build: context: . dockerfile: Dockerfile target: production image: emfoursolutions/trakbridge:latest container_name: trakbridge restart: unless-stopped environment: <<: [*common-environment, *common-secrets] secrets: - db_password - secret_key - tb_master_key - ldap_bind_password - oidc_client_secret ports: - "5000:5000" # Change first port if you need external access on different port volumes: - ./logs:/app/logs - ./data:/app/data - ./plugins:/app/external_plugins - ./config:/app/external_config - ./secrets:/app/secrets - ./backups:/app/backups healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5000/api/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s depends_on: postgres: condition: service_healthy required: false mysql: condition: service_healthy required: false networks: - trakbridge # Internal for DB communication - frontend # External for Traefik # ============================================================================= # PostgreSQL Database (Optional) # ============================================================================= postgres: image: postgres:17-alpine container_name: trakbridge-postgres restart: unless-stopped profiles: ["postgres"] command: | postgres -c shared_buffers=256MB -c effective_cache_size=1GB -c maintenance_work_mem=64MB -c checkpoint_completion_target=0.9 -c wal_buffers=16MB -c default_statistics_target=100 -c random_page_cost=1.1 -c effective_io_concurrency=200 -c work_mem=4MB -c min_wal_size=1GB -c max_wal_size=4GB -c max_connections=200 -c shared_preload_libraries='pg_stat_statements' -c track_activity_query_size=2048 -c log_line_prefix='%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h ' -c log_statement=none -c log_temp_files=0 environment: POSTGRES_DB: trakbridge POSTGRES_USER: trakbridge POSTGRES_PASSWORD_FILE: /run/secrets/db_password POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256" secrets: - db_password volumes: - postgres_data:/var/lib/postgresql/data - ./docker/init-scripts/postgres:/docker-entrypoint-initdb.d:ro healthcheck: test: | pg_isready -U trakbridge -d trakbridge && psql -U trakbridge -d trakbridge -c "SELECT 1" > /dev/null 2>&1 && psql -U trakbridge -d trakbridge -c "SELECT COUNT(*) FROM pg_stat_activity" > /dev/null 2>&1 interval: 30s timeout: 10s retries: 5 start_period: 45s networks: - trakbridge deploy: resources: limits: memory: 1.5G reservations: memory: 512M # ============================================================================= # MySQL Database (Optional) # ============================================================================= mysql: image: mariadb:11.8 container_name: trakbridge-mysql restart: unless-stopped profiles: ["mysql"] command: - --max-connections=200 - --wait-timeout=600 - --interactive-timeout=600 - --net-read-timeout=120 - --net-write-timeout=120 - --max-allowed-packet=64M - --innodb-buffer-pool-load-at-startup=ON - --innodb-buffer-pool-dump-at-shutdown=ON - --innodb-log-file-size=256M - --innodb-flush-log-at-trx-commit=1 - --bind-address=0.0.0.0 - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --skip-name-resolve - --innodb-buffer-pool-size=512M - --connect-timeout=60 - --slave-net-timeout=120 - --thread-cache-size=50 - --query-cache-type=1 - --query-cache-size=64M - --tmp-table-size=64M - --max-heap-table-size=64M - --innodb-lock-wait-timeout=50 - --log-warnings=2 environment: MARIADB_DATABASE: trakbridge MARIADB_USER: trakbridge MARIADB_PASSWORD_FILE: /run/secrets/db_password MARIADB_ROOT_PASSWORD_FILE: /run/secrets/db_password MARIADB_AUTO_UPGRADE: "1" MARIADB_MYSQL_LOCALHOST_USER: "1" secrets: - db_password volumes: - mysql_data:/var/lib/mysql - ./docker/init-scripts/mysql:/docker-entrypoint-initdb.d:ro healthcheck: test: | mariadb-admin ping -h localhost -u root -p$$(cat /run/secrets/db_password) && mariadb -u root -p$$(cat /run/secrets/db_password) -e "SELECT 1" > /dev/null 2>&1 interval: 30s timeout: 10s retries: 5 start_period: 45s networks: - trakbridge deploy: resources: limits: memory: 1G reservations: memory: 512M # Nginx reverse proxy removed - Traefik handles reverse proxy # ============================================================================= # Networks & Volumes # ============================================================================= networks: trakbridge: driver: bridge internal: true # DB network needs no internet egress frontend: external: true name: frontend volumes: postgres_data: driver: local mysql_data: driver: local # ============================================================================= # Secrets # ============================================================================= secrets: db_password: file: ./secrets/db_password secret_key: file: ./secrets/secret_key tb_master_key: file: ./secrets/tb_master_key ldap_bind_password: file: ./secrets/ldap_bind_password oidc_client_secret: file: ./secrets/oidc_client_secret