Quick Start
Copy.env.example to .env and configure required variables. All configuration can also be provided via the config/hoodcloud.yaml file with environment variable overrides.
Configuration Hierarchy
HoodCloud uses a two-tier configuration system:- Primary: YAML configuration file (
config/hoodcloud.yaml) - Override: Environment variables (take precedence over YAML)
HOODCLOUD_CONFIG environment variable can specify a custom config file path.
Variables by Category
Configuration Management
HTTP Server
Database (PostgreSQL)
Database Pool Configuration
Per-Service Connection Pool Sizing:
Connection Budget Formula:
sum(MaxConns × instances) < PostgreSQL max_connections
Example: With 2 instances per service: (5×2) + (5×2) + (10×2) + (10×2) + (10×2) = 80 < 100 (default max_connections)
Redis
Temporal
HashiCorp Vault
Vault is the secrets provider for all application secrets. AWS credentials may still be needed for S3 key backups (either via environment or Vault AWS secrets engine). Local Development: All Vault variables below are auto-configured bydocker-compose.dev.yml. The vault-dev-init.sh sidecar seeds secrets and writes AppRole credentials to a shared volume. No manual Vault configuration is needed for local dev.
See also: Vault Secret Structure for the full Vault KV layout and all credential fields.Key notes:
sealed_box_public_keyandsealed_box_private_keyare mandatory — api-server and orchestrator fail fast at startup without them. See Vault - Generate X25519 Keypair.- Payment mTLS fields (
payment_client_cert,payment_client_key,payment_ca_cert) are optional — only needed when payment service integration is enabled. - Incident notification fields are optional. When present, health-evaluator enables the corresponding notification channels. If none are configured, incidents are tracked in DB only.
- Generate role_id:
vault read -field=role_id auth/approle/role/hoodcloud-control-plane/role-id - Generate secret_id:
vault write -f -field=secret_id auth/approle/role/hoodcloud-control-plane/secret-id - Deploy secret_id to
/opt/hoodcloud/secrets/vault-secret-idon the service host withchmod 644 - The host path is mounted into containers as
/secrets/vault-secret-idvia the/opt/hoodcloud/secrets:/secrets:rovolume mount - Service reads the secret_id file during AppRole authentication
AWS (S3 Key Backups)
gRPC Server (Ops Agent Communication)
gRPC Rate Limiting
Cloud Provider Defaults
Terraform
Terraform Operation Timeouts
Command Execution
Chain Configurations
Dynamic Chain Config Provider
The control plane services can load chain configs from either local filesystem or S3 with hot-reload support.
Version Modes:
S3 Bucket Structure:
Config-as-Code (Ops Agent Runtime)
These variables control config bundle distribution to ops-agents (separate from control plane loading):Ops Agent
Ops Agent Runtime (on VMs)
The ops-agent supports two configuration modes:- YAML + Environment Override: Set
OPS_AGENT_CONFIGto a YAML config file path. Environment variables override YAML values. - Environment-Only (Legacy): If
OPS_AGENT_CONFIGis not set, configuration loads purely from environment variables.
config/ops-agent.yaml.example for a YAML configuration template.
Health Evaluator
Uptime Worker (Hardcoded Defaults)
The UptimeWorker runs insidehealth-evaluator and uses hardcoded defaults (no environment variables). Values are defined in internal/defaults/defaults.go:
Observability
Telemetry (OpenTelemetry)
Authentication (Auth Server)
JWT RS256 (Asymmetric)
RS256 uses asymmetric cryptography: the auth-server signs tokens with a private key, and api-server verifies with the public key.
Audience claim: When
JWT_AUDIENCE is set, the auth-server includes it in every issued token and all verifying services (api-server, agent-gateway) validate that incoming tokens contain this exact audience value. A mismatch causes token validation to fail with 401 Unauthorized. If deploying multiple services, ensure JWT_AUDIENCE is consistent across all of them. Omitting JWT_AUDIENCE skips audience validation entirely (backward compatibility).
Key Generation:
- Vault (
jwt_private_key,jwt_public_keyfields) - File paths (
JWT_PRIVATE_KEY_FILE,JWT_PUBLIC_KEY_FILE) | SIWE_DOMAIN | No | localhost | public | (Deprecated) SIWE message domain. Only used whenAUTH_PROVIDER=siweorboth. | | SIWE_URI | No | http://localhost:3000 | public | (Deprecated) SIWE message URI. Only used whenAUTH_PROVIDER=siweorboth. | | AUTH_NONCE_EXPIRY | No | 5m | public | (Deprecated) Auth nonce expiry time. Only used whenAUTH_PROVIDER=siweorboth. | | AUTH_RATE_LIMIT_PER_MINUTE | No | 20 | public | Rate limit for auth endpoints per IP | | AUTH_MAX_REFRESH_TOKENS_PER_USER | No | 10 | public | Maximum concurrent active sessions per user | | AUTH_ALLOWED_ORIGINS | No | - | public | Comma-separated allowed CORS origins for auth server |
Clerk (Primary Auth Provider)
API Security
NATS Event Streaming
Cross-repo dependency: The PAYMENTS stream is managed by the payment service repository. Its replica count must be configured separately in the payment service.
NATS Multi-Account Authentication
WhenNATS_ACCOUNTS_ENABLED=true, each service component connects with its own account and subject-level permissions. Tokens are delivered to ops-agents via gRPC after registration (no shared token in cloud-init).
Payment Service Integration
The payment service runs as a separate microservice with its own database. These variables configure the main app’s connection to the payment service.Payment Service Client (gRPC)
mTLS Credentials via Vault:
When using Vault for secrets management, payment service mTLS credentials can be stored in the app credentials secret instead of using file paths. Add these fields to your app credentials JSON:
Payment Event Consumer (NATS)
Payment Service (Separate Microservice)
The payment service runs as an isolated microservice with its own configuration. Seepayment-service/config/config.example.yaml for full configuration reference.
Payment Service Vault Integration
When Vault is enabled for the payment service, it provides AWS credentials for S3 operations instead of static environment variables.
Note: Payment service uses koanf for configuration (same pattern as main app). Environment variables override YAML configuration values.
Tempo Crypto Provider
The payment service supports Tempo network TIP-20 stablecoins for crypto payments. Tempo usesTransferWithMemo events for exact payment matching via memo field (payment ID as bytes32).
Stripe Payment Provider
The payment service supports Stripe Checkout for card payments. Stripe secrets are sourced from Vault atsecret/payment-service/credentials.
Vault-Sourced Secrets:
These values are loaded by the payment service Vault client at startup and injected into the Stripe adapter configuration. They are not set via environment variables.
Cloud Provider Credentials
Hetzner
OVH
OVH credentials are required only when using OVH providers (ovh-public-cloud, ovh-vps, ovh-dedicated).
Create API credentials at: https://api.ovh.com/createToken/
OVH Provider Types:
E2E Testing
Docker Compose Environment
Payment Service (docker-compose.payment.yml)
These variables are used when running the payment service viadocker compose -f docker-compose.yml -f docker-compose.payment.yml up:
Variables by Service
auth-server
Required:- DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
- REDIS_HOST (for Redis-backed rate limiting)
- JWT_PRIVATE_KEY_FILE + JWT_PUBLIC_KEY_FILE (or via Vault)
- AUTH_CLERK_SECRET_KEY, AUTH_CLERK_AUTHORIZED_PARTY, AUTH_CLERK_WEBHOOK_SIGNING_SECRET (when using Clerk, which is the default)
- SERVER_HOST, SERVER_PORT
- DB_PORT, DB_SSL_MODE, DB_MAX_CONNS, DB_MIN_CONNS, DB_MAX_CONN_LIFETIME, DB_MAX_CONN_IDLE_TIME, DB_STATEMENT_TIMEOUT
- REDIS_PORT, REDIS_PASSWORD, REDIS_DB
- JWT_ACCESS_TOKEN_TTL, JWT_REFRESH_TOKEN_TTL, JWT_ISSUER, JWT_AUDIENCE
- AUTH_PROVIDER (default:
clerk) - AUTH_RATE_LIMIT_PER_MINUTE, AUTH_ALLOWED_ORIGINS
- ENVIRONMENT, LOG_LEVEL
- SIWE_DOMAIN, SIWE_URI, AUTH_NONCE_EXPIRY (only needed when
AUTH_PROVIDER=siweorboth)
api-server
Required:- SERVER_PUBLIC_URL
- DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
- REDIS_HOST
- TEMPORAL_HOST
- AWS_S3_BUCKET
- SERVER_HOST, SERVER_PORT, SERVER_READ_TIMEOUT, SERVER_WRITE_TIMEOUT
- DB_PORT, DB_SSL_MODE, DB_MAX_CONNS, DB_MIN_CONNS, DB_MAX_CONN_LIFETIME, DB_MAX_CONN_IDLE_TIME, DB_STATEMENT_TIMEOUT
- REDIS_PORT, REDIS_PASSWORD, REDIS_DB
- TEMPORAL_PORT, TEMPORAL_NAMESPACE, TEMPORAL_TASK_QUEUE
- AWS_REGION, AWS_ENDPOINT_URL, AWS_S3_BACKUP_PREFIX
- OPS_AGENT_BINARIES_DIR
- CHAIN_PROFILES_DIR, CHAIN_CONFIGS_SOURCE, CHAINS_S3_BUCKET, CHAINS_S3_REGION, CHAINS_S3_PREFIX, CHAINS_CHECK_INTERVAL, CHAIN_CONFIGS_WATCH
- JWT_PUBLIC_KEY_FILE, JWT_AUDIENCE for JWT validation (RS256)
- AUTH_PROVIDER, AUTH_CLERK_SECRET_KEY, AUTH_CLERK_AUTHORIZED_PARTY (when Clerk provider enabled; no webhook secret — api-server does not handle webhooks)
- API_AUTH_ENABLED, API_RATE_LIMIT_ENABLED, API_RATE_LIMIT_REQUESTS
- PAYMENT_CONSUMER_ENABLED, PAYMENT_CONSUMER_URL, PAYMENT_CONSUMER_STREAM_NAME (for processing payment events)
- ENVIRONMENT, LOG_LEVEL
agent-gateway
Required:- DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
- REDIS_HOST
- GRPC_PUBLIC_URL
- DB_PORT, DB_SSL_MODE, DB_MAX_CONNS, DB_MIN_CONNS, DB_MAX_CONN_LIFETIME, DB_MAX_CONN_IDLE_TIME, DB_STATEMENT_TIMEOUT
- REDIS_PORT, REDIS_PASSWORD, REDIS_DB
- AWS_REGION, AWS_ENDPOINT_URL
- GRPC_HOST, GRPC_PORT, GRPC_USE_TLS, GRPC_CERT_FILE, GRPC_KEY_FILE, GRPC_CA_FILE
- GRPC_CONFIG_SIGNING_KEY
- GRPC_RATE_LIMIT_RPS, GRPC_RATE_LIMIT_BURST, GRPC_RATE_LIMIT_CLEANUP_INTERVAL
- COMMAND_PROGRESS_TTL
- NATS_ENABLED, NATS_URL, NATS_STREAM_NAME, NATS_MAX_MESSAGE_SIZE
- ENVIRONMENT, LOG_LEVEL
orchestrator
Required:- DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
- REDIS_HOST
- TEMPORAL_HOST
- AWS_S3_BUCKET
- SERVER_PUBLIC_URL, GRPC_PUBLIC_URL
- HCLOUD_TOKEN (if using Hetzner provider)
- DB_PORT, DB_SSL_MODE, DB_MAX_CONNS, DB_MIN_CONNS, DB_MAX_CONN_LIFETIME, DB_MAX_CONN_IDLE_TIME, DB_STATEMENT_TIMEOUT
- REDIS_PORT, REDIS_PASSWORD, REDIS_DB
- TEMPORAL_PORT, TEMPORAL_NAMESPACE, TEMPORAL_TASK_QUEUE
- AWS_REGION, AWS_ENDPOINT_URL, AWS_S3_BACKUP_PREFIX
- GRPC_USE_TLS, GRPC_CONFIG_SIGNING_KEY
- TERRAFORM_BINARY, TERRAFORM_STATE_DIR, TERRAFORM_PARALLELISM
- TERRAFORM_STATE_BACKEND, TERRAFORM_S3_BUCKET, TERRAFORM_S3_REGION, TERRAFORM_DYNAMODB_TABLE
- TERRAFORM_INIT_TIMEOUT, TERRAFORM_PLAN_TIMEOUT, TERRAFORM_APPLY_TIMEOUT, TERRAFORM_DESTROY_TIMEOUT, TERRAFORM_OUTPUT_TIMEOUT
- COMMAND_PROGRESS_TTL
- SKIP_TERRAFORM, DEV_MODE
- CHAIN_PROFILES_DIR, CHAIN_CONFIGS_SOURCE, CHAINS_S3_BUCKET, CHAINS_S3_REGION, CHAINS_S3_PREFIX, CHAINS_CHECK_INTERVAL, CHAIN_CONFIGS_WATCH
- CHAIN_CONFIGS_ENABLED, CONFIG_BUNDLE_VERSION, CHAIN_CONFIGS_S3_BUCKET, CHAIN_CONFIGS_S3_REGION, CHAIN_CONFIGS_URL_EXPIRY, CHAIN_CONFIGS_LOCAL_DIR, S3_PUBLIC_ENDPOINT_URL (for ops-agent config bundles)
- OPS_AGENT_VERSION
- DEFAULT_PROVIDER, DEFAULT_REGION
- OVH_ENDPOINT, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY, OVH_CLOUD_PROJECT_SERVICE (if using OVH providers)
- ENVIRONMENT, LOG_LEVEL
health-evaluator
Required:- DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
- TEMPORAL_HOST
- DB_PORT, DB_SSL_MODE, DB_MAX_CONNS, DB_MIN_CONNS, DB_MAX_CONN_LIFETIME, DB_MAX_CONN_IDLE_TIME, DB_STATEMENT_TIMEOUT
- TEMPORAL_PORT, TEMPORAL_NAMESPACE, TEMPORAL_TASK_QUEUE
- AWS_REGION, AWS_S3_BUCKET, AWS_S3_BACKUP_PREFIX (for backup cleanup)
- HEALTH_EVALUATION_INTERVAL, HEALTH_HEARTBEAT_TIMEOUT, HEALTH_MIGRATION_COOLDOWN
- SUBSCRIPTION_CLEANUP_INTERVAL
- MAINTENANCE_CLEANUP_INTERVAL, MAINTENANCE_CLEANUP_TIMEOUT
- NATS_ENABLED, NATS_URL, NATS_STREAM_NAME, NATS_CONSUMER_NAME, NATS_MAX_MESSAGE_SIZE, NATS_STREAM_REPLICAS
- VICTORIA_METRICS_URL, METRICS_CONSUMER_NAME (for observation metrics ingestion and policy evaluation)
- EVALUATION_CONCURRENCY (for parallel chain policy evaluation)
- CIRCUIT_BREAKER_FAILURE_THRESHOLD, CIRCUIT_BREAKER_SUCCESS_THRESHOLD, CIRCUIT_BREAKER_TIMEOUT (for metrics ingester protection)
- CHAIN_PROFILES_DIR, CHAIN_CONFIGS_SOURCE, CHAINS_S3_BUCKET, CHAINS_S3_REGION, CHAINS_S3_PREFIX, CHAINS_CHECK_INTERVAL (for loading observation specs and policies)
- ENVIRONMENT, LOG_LEVEL
- UptimeWorker — materializes rolling uptime buckets (5m interval, 500 batch size, 90-day retention). See Deployment & Operations - Rolling Uptime.
incident_slack_webhook_url— Slack incoming webhook URL (optional, enables Slack notifications)incident_telegram_bot_token— Telegram bot token (optional, enables Telegram notifications)incident_telegram_chat_id— Telegram chat ID (required if bot token is set)incident_email_api_url— Email delivery service API URL (optional, enables Email notifications)incident_email_api_key— Email delivery service API key (required if API URL is set)incident_email_from— Sender email address for incident notificationsincident_email_to— Recipient email address for incident notificationsincident_webhook_url— Outbound webhook URL (optional, enables Webhook notifications)incident_webhook_secret— Shared secret sent inX-Webhook-Secretheader for request verification
secret/hoodcloud/app-credentials, not from environment variables. The health-evaluator initializes the incident notification pipeline at startup based on which credentials are present.
ops-agent (on VMs)
Required:- NODE_ID
- GRPC_URL (or CONTROL_PLANE_URL for backward compatibility)
- OPS_AGENT_CONFIG (path to YAML configuration file)
- NODE_TOKEN
- GRPC_USE_TLS, GRPC_PORT, GRPC_ADDRESS
- TLS_CERT_FILE, TLS_KEY_FILE, TLS_CA_FILE
- CHAIN_PROFILE_ID, CHAIN_DATA_DIR, CHAIN_RPC_PORT, CHAIN_TYPE
- HEARTBEAT_INTERVAL, GRACE_PERIOD
- CONFIG_SIGNING_PUBLIC_KEY, REQUIRE_CONFIG_SIGNATURE
- CONFIG_DIR, CONFIG_VERSION
- METRICS_ENABLED, METRICS_PORT
- OBSERVATION_ENABLED, NATS_URL, HOST_ID (for observation metrics transport; NATS auth via JWT operator mode)
- SYSTEM_METRICS_INTERVAL, SYSTEM_METRICS_DATA_PATH (for system metrics collection)
- ENVIRONMENT, LOG_LEVEL
payment-service (Isolated Microservice)
Required:- DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
- TLS_CERT_FILE, TLS_KEY_FILE, TLS_CA_FILE (unless TLS_INSECURE=true)
- TLS_ALLOWED_CN (for client certificate CN verification)
- VAULT_ADDRESS, VAULT_ROLE_ID, VAULT_SECRET_ID_PATH
- VAULT_TLS_CA_FILE, VAULT_APP_CREDENTIALS_PATH
- PAYMENT_CONFIG
- GRPC_ADDRESS, HTTP_ADDRESS, METRICS_ADDRESS
- DB_PORT, DB_SSL_MODE, DB_MAX_CONNS, DB_MIN_CONNS
- NATS_URL, NATS_STREAM_NAME, NATS_CTRL_SIGNING_SEED, NATS_CTRL_ACCOUNT_PUB
- PRICING_CONFIG_PATH
- TLS_INSECURE (development only)
- VAULT_NAMESPACE, VAULT_TLS_SKIP_VERIFY (dev only — rejected in production), VAULT_CACHE_TTL
- OTEL_ENABLED, OTEL_COLLECTOR_URL, OTEL_SAMPLE_RATIO
- TEMPO_ENABLED, TEMPO_RPC_URL, TEMPO_RECEIVER_ADDRESS, TEMPO_CHAIN_ID, TEMPO_POLL_INTERVAL, TEMPO_TOKEN_ALPHAUSD, TEMPO_TOKEN_BETAUSD
- STRIPE_ENABLED (Stripe secrets sourced from Vault, not environment variables)
Security Classifications
Secret (Must Never Be Exposed)
These variables contain credentials, tokens, or cryptographic keys:- JWT_PRIVATE_KEY_FILE (file content is secret)
- DB_PASSWORD
- REDIS_PASSWORD
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- VAULT_ROLE_ID
- VAULT_SECRET_ID_PATH (file content is secret)
- GRPC_KEY_FILE
- GRPC_CONFIG_SIGNING_KEY
- TLS_KEY_FILE
- HCLOUD_TOKEN
- OVH_APPLICATION_KEY
- OVH_APPLICATION_SECRET
- OVH_CONSUMER_KEY
- E2E_DB_PASSWORD
- POSTGRES_PASSWORD
- GRAFANA_ADMIN_PASSWORD
- NGROK_AUTHTOKEN
- NATS_JWT_CTRL_ACCOUNT_PUB (sensitive, not secret — public key only)
- NATS_CTRL_SIGNING_SEED (secret — loaded from Vault in production)
- AUTH_CLERK_SECRET_KEY
- AUTH_CLERK_WEBHOOK_SIGNING_SECRET
- Never commit to version control
- Store in secure secret management systems (HashiCorp Vault)
- Use environment-specific .env files (gitignored)
- Rotate regularly
- Use IAM roles/instance profiles instead of static credentials where possible
Sensitive (Should Not Be Public)
These variables contain internal URLs, usernames, or configuration that should not be publicly disclosed:- SERVER_PUBLIC_URL
- GRPC_PUBLIC_URL
- DB_HOST, DB_USER, DB_NAME
- REDIS_HOST
- TEMPORAL_HOST
- AWS_S3_BUCKET
- AWS_ENDPOINT_URL
- VAULT_ADDR
- VAULT_MASTER_KEY_PATH, VAULT_APP_CREDENTIALS_PATH
- VAULT_TLS_CA_FILE
- JWT_PUBLIC_KEY_FILE
- GRPC_CERT_FILE, GRPC_CA_FILE
- TLS_CERT_FILE, TLS_CA_FILE
- NODE_ID
- CONTROL_PLANE_URL, GRPC_URL
- CONFIG_SIGNING_PUBLIC_KEY
- LOKI_URL, PROMETHEUS_URL, VICTORIA_METRICS_URL
- NATS_URL, NATS_PUBLIC_URL
- OPS_AGENT_DOWNLOAD_URL
- S3_PUBLIC_ENDPOINT_URL
- E2E_API_URL, E2E_GRPC_ADDRESS, E2E_DB_HOST, E2E_DB_USER, E2E_DB_NAME, E2E_TEMPORAL_HOST, E2E_SSH_KEY_PATH
- POSTGRES_USER
- GRAFANA_ADMIN_USER
- CHAIN_CONFIGS_S3_BUCKET
- OVH_CLOUD_PROJECT_SERVICE
- TERRAFORM_S3_BUCKET
- TERRAFORM_DYNAMODB_TABLE
Public (Safe to Commit)
These variables contain non-sensitive configuration:- All timeouts, intervals, and thresholds
- Port numbers
- Feature flags (API_AUTH_ENABLED, NATS_ENABLED, etc.)
- Default values and limits
- ENVIRONMENT, LOG_LEVEL
- Public configuration like CHAIN_PROFILES_DIR
Production Checklist
See: Deployment Checklist for the full pre-deployment checklist covering configuration, authentication, security, and infrastructure validation.
Variable Reference by File
Source Code References
internal/config/config.go- Authoritative source for all environment variable mappings
- Implements koanf-based configuration with env var overrides
- TerraformConfig: timeout fields (init, plan, apply, destroy, output)
- CommandsConfig: progress_ttl field
- Environment variable to config path mappings
- TERRAFORM_*_TIMEOUT and COMMAND_PROGRESS_TTL mappings
- Ops agent configuration loading with YAML support
- LoadFromFile() for YAML configuration
- LoadConfig() with OPS_AGENT_CONFIG support
- All NODE_ID, GRPC_URL, CHAIN_* variables
- ENVIRONMENT variable usage for logging
- HTTP-only API server (gRPC moved to agent-gateway)
- gRPC server for ops-agent communication
- Uses COMMAND_PROGRESS_TTL for Redis progress storage
- GRPC_* variables for server configuration
- ENVIRONMENT variable usage
- HCLOUD_TOKEN direct usage (passed to Terraform)
- TERRAFORM_*_TIMEOUT variables for provisioning operations
- COMMAND_PROGRESS_TTL for progress reader
- ENVIRONMENT variable usage
- HOODCLOUD_CONFIG file path loading
- LOG_LEVEL parsing and configuration
- Timeout configuration from Config struct
- Falls back to defaults.Terraform.* when not configured
- ProgressStore with configurable TTL
- Uses functional options pattern (WithProgressTTL)
- Falls back to defaults.Commands.ProgressTTL
- All E2E_* test configuration variables
Configuration File References
docker-compose.dev.yml- Development environment defaults
- All service environment configurations
- E2E testing environment
- Isolated ports and test-specific configuration
- Production-like Docker Compose setup
- Template with all user-configurable variables
- YAML configuration structure
- Default values for all settings
Troubleshooting
Missing Required Variables
If services fail to start with missing variable errors:- Check
.envfile exists and contains required variables - Verify environment variables are exported in your shell
- For Docker Compose, ensure
.envis in the same directory asdocker-compose.yml - Check service-specific required variables in “Variables by Service” section
Configuration Not Applied
If environment variables seem to be ignored:- YAML file values take precedence unless overridden by environment variables
- Check
HOODCLOUD_CONFIGis pointing to the correct file - Verify variable names match exactly (case-sensitive)
- For Docker, check environment variables are passed through in docker-compose.yml
Connection Issues
If services can’t connect to each other:- Verify hostnames match service names in Docker Compose
- Check port numbers match between services
- Ensure URLs include protocol (http://, nats://, etc.)
- For external VMs, ensure *_PUBLIC_URL variables are set to externally-accessible addresses
Migration Guide
From Environment-Only to YAML + Environment
- Create
config/hoodcloud.yamlwith your base configuration - Set environment variables only for values that differ from YAML or are secrets
- Set
HOODCLOUD_CONFIG=config/hoodcloud.yaml - Restart services
From Development to Production
- Copy
.env.exampleto.env.production - Replace all placeholder values with production values
- Move all secrets to HashiCorp Vault
- Configure Vault AppRole authentication
- Enable security features (TLS, auth, rate limiting)
- Set appropriate timeouts and intervals for production scale