Getting Started¶
Deploy ComposeFlux and manage Docker Compose stacks via GitOps.
Prerequisites¶
- Docker with Compose v2+
- Git repository with Compose stacks
- Secrets manager: Bitwarden or Infisical (required)
- SSH key for Git access (store in secrets manager or mount as volume)
Environment Variables¶
Required¶
| Variable | Description |
|---|---|
SECRETS_PROVIDER |
Secrets manager: bitwarden or infisical (required) |
GIT_REPO_URL |
Git repository SSH URL (e.g., git@github.com:user/repo.git) |
STACK_PATH |
Path to stacks directory in repo (relative to repo root) |
Bitwarden (when SECRETS_PROVIDER=bitwarden):
| Variable | Description | Default |
|---|---|---|
BITWARDEN_ACCESS_TOKEN |
Machine account access token | |
BITWARDEN_ORGANIZATION_ID |
Organization ID | |
BITWARDEN_PROJECT_ID |
Project ID | |
BITWARDEN_API_URL |
Bitwarden API URL | https://vault.bitwarden.com/api |
BITWARDEN_IDENTITY_URL |
Bitwarden Identity URL | https://vault.bitwarden.com/identity |
Infisical (when SECRETS_PROVIDER=infisical):
| Variable | Description | Default |
|---|---|---|
INFISICAL_CLIENT_ID |
Universal Auth client ID | |
INFISICAL_CLIENT_SECRET |
Universal Auth client secret | |
INFISICAL_ENVIRONMENT |
Environment slug (e.g., prod) |
|
INFISICAL_PROJECT_ID |
Project ID | |
INFISICAL_SITE_URL |
Infisical site URL | https://app.infisical.com |
INFISICAL_SECRET_PATH |
Secret path in Infisical project | / |
Optional¶
| Variable | Description | Default |
|---|---|---|
GIT_DEPLOY_KEY_SECRET_REF |
Deploy key secret reference (name or ID) in secrets manager (See Deploy Key Secret Reference) | SSH_PRIVATE_KEY |
GIT_SSH_KEY_PATH |
SSH key path inside container | /.ssh/composeflux_id_rsa |
GIT_CLONE_PATH |
Local clone directory | /opt/compose-stack |
GIT_INTERVAL |
Git sync interval | 5m |
CONFIG_FILE |
Stack config file name (see Stack Configuration) | stack.yml |
LOG_LEVEL |
Log level (debug/info/warn/error) |
info |
LOG_FORMAT |
Log format (console/json) |
console |
LOG_ADD_SOURCE |
Add source location to logs | false |
Commands¶
ComposeFlux supports two commands:
Usage: composeflux <command> [flags]
A GitOps continuous deployment tool for Docker Compose.
Flags:
-h, --help Show context-sensitive help.
--log-format="console" Set the output format of the logs. Must be "console" or "json" ($LOG_FORMAT).
--log-level=INFO Set the log level. Must be "DEBUG", "INFO", "WARN" or "ERROR" ($LOG_LEVEL).
--log-add-source Whether to add source file and line number to log records ($LOG_ADD_SOURCE).
--version Print version information and exit
Commands:
run Run ComposeFlux in daemon mode (continuous reconciliation)
sync Perform a one-shot sync and deploy
Run "composeflux <command> --help" for more information on a command.
run- Daemon mode with continuous reconciliation (default). Performs an initial sync at startup, then checks the Git repository for changes at configured intervals (default: 5 minutes).sync- One-shot sync and deploy. Manually triggers immediate synchronization. Useful when you update secrets in your secrets manager but haven't made Git changes. See Hash-Based Change Detection.
# Daemon mode (initial sync at startup, then checks Git every 5 minutes)
composeflux run
# One-shot mode - manually trigger sync
composeflux sync
Important: After the initial startup sync, the run command fetches secrets and deploys changes only when Git updates are detected. If you update secrets in your secrets manager without changing anything in Git, run composeflux sync manually to apply updated secrets. See Hash-Based Change Detection.
Deploy ComposeFlux¶
1. Set up Secrets Manager:
2. Configure Git Access:
- GitHub Deploy Keys Setup - Recommended for secure read-only access
3. Create .env file:
# Required - Common
GIT_REPO_URL=git@github.com:user/stacks-repo.git
STACK_PATH=stacks
# Required - Choose one secrets provider:
# Option A: Bitwarden
SECRETS_PROVIDER=bitwarden
GIT_DEPLOY_KEY_SECRET_REF=aaaaaaa-bbbbb-bbbb-cccc-ddddd
BITWARDEN_ACCESS_TOKEN=your-access-token
BITWARDEN_ORGANIZATION_ID=your-org-id
BITWARDEN_PROJECT_ID=your-project-id
# Option B: Infisical
# SECRETS_PROVIDER=infisical
# GIT_DEPLOY_KEY_SECRET_REF=SSH_PRIVATE_KEY (Default)
# INFISICAL_CLIENT_ID=your-client-id
# INFISICAL_CLIENT_SECRET=your-client-secret
# INFISICAL_ENVIRONMENT=prod
# INFISICAL_PROJECT_ID=your-project-id
4. Create compose.yml:
services:
composeflux:
image: ghcr.io/veerendra2/composeflux:latest
container_name: composeflux
restart: unless-stopped
environment:
# Git Configuration
GIT_REPO_URL: ${GIT_REPO_URL}
STACK_PATH: ${STACK_PATH}
# GIT_INTERVAL: 5m # Sync interval
# Secrets Manager - Bitwarden
SECRETS_PROVIDER: ${SECRETS_PROVIDER}
GIT_DEPLOY_KEY_SECRET_REF: ${GIT_DEPLOY_KEY_SECRET_REF}
BITWARDEN_ACCESS_TOKEN: ${BITWARDEN_ACCESS_TOKEN}
BITWARDEN_ORGANIZATION_ID: ${BITWARDEN_ORGANIZATION_ID}
BITWARDEN_PROJECT_ID: ${BITWARDEN_PROJECT_ID}
# Secrets Manager - Infisical (comment out Bitwarden above if using this)
# SECRETS_PROVIDER: infisical
# GIT_DEPLOY_KEY_SECRET_REF: ${GIT_DEPLOY_KEY_SECRET_REF}
# INFISICAL_CLIENT_ID: ${INFISICAL_CLIENT_ID}
# INFISICAL_CLIENT_SECRET: ${INFISICAL_CLIENT_SECRET}
# INFISICAL_ENVIRONMENT: ${INFISICAL_ENVIRONMENT}
# INFISICAL_PROJECT_ID: ${INFISICAL_PROJECT_ID}
# INFISICAL_SITE_URL: https://app.infisical.com
# Logging
# LOG_LEVEL: info
# LOG_FORMAT: console # console or json
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# Optional: Custom SSH known_hosts
# - ./ssh_known_hosts:/etc/ssh/ssh_known_hosts:ro
# Optional: Mount local SSH key instead of fetching from secrets manager
# Uncomment below and set GIT_DEPLOY_KEY_SECRET_REF="" in environment above
# - ~/.ssh/id_rsa:/.ssh/composeflux_id_rsa:ro
Mount SSH Key¶
If you prefer to mount your SSH key directly instead of storing it in the secrets manager:
- Set
GIT_DEPLOY_KEY_SECRET_REF=""(empty string) in environment variables to disable fetch - Mount your SSH key to the container at
GIT_SSH_KEY_PATHlocation (default:/.ssh/composeflux_id_rsa)
Deploy Key Secret Reference¶
ComposeFlux can fetch your SSH deploy key from the secrets manager during startup, so it can clone private repositories without mounting a local key.
How GIT_DEPLOY_KEY_SECRET_REF works:
- When set to a value (e.g.,
SSH_PRIVATE_KEYor a Bitwarden secret ID), ComposeFlux fetches that secret from your secrets manager - Bitwarden: Uses it as the secret ID to fetch (see Bitwarden Add Secrets)
- Infisical: Uses it as the secret key name to fetch
- The fetched content must be your SSH private key
- When set to
""(empty string), skips fetch and uses mounted key atGIT_SSH_KEY_PATH
Example:
environment:
GIT_DEPLOY_KEY_SECRET_REF: "" # Disable fetch from secrets manager
# GIT_SSH_KEY_PATH: /.ssh/composeflux_id_rsa # Optional: custom path
volumes:
- ~/.ssh/id_rsa:/.ssh/composeflux_id_rsa:ro
5. Start ComposeFlux:
# Default: Run in daemon mode (continuous reconciliation)
docker compose up -d
docker compose logs -f
Verify Deployment¶
# Check logs
docker compose logs -f
# List managed stacks (should show containers with composeflux label)
docker ps --filter "label=compose.stack.managed-by=composeflux"
# List all compose projects
docker compose ls