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 (optional, for secrets injection and deploy key fetching)
- SSH key for Git access (store in secrets manager or mount as volume)
Environment Variables¶
Required¶
| Variable | Description |
|---|---|
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) |
Optional - Secrets Provider¶
| Variable | Description |
|---|---|
SECRETS_PROVIDER |
Secrets manager: bitwarden or infisical (optional) |
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. Supports comma-separated paths (e.g., /generic,/apps/prod). If the same secret exists in multiple paths, the last path's value takes precedence. |
/ |
Optional¶
| Variable | Description | Default |
|---|---|---|
GIT_DEPLOY_KEY_SECRET_REF |
Deploy key secret reference (name or ID) in secrets manager (See Deploy Key Secret Reference) | |
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 |
HEALTH_RECONCILE_INTERVAL |
Interval for proactive stack health reconciliation. ComposeFlux redeploys any stack with a non-running container (unless it is a completed init container). Set to e.g. 5m to enable. |
disabled |
IMAGE_UPDATE_SCHEDULE |
Cron expression for Docker image update checks, e.g. 0 3 * * *. Empty = disabled. |
"" |
GIT_BRANCH |
Git branch to track | main |
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 |
REMOVE_ORPHANS |
Remove orphan containers during deploy | true |
PRUNE_INTERVAL |
Interval for periodic Docker resource pruning (images, volumes, build cache). Only runs when all managed stacks are healthy. Set to 0 to disable. |
24h |
Warning
When PRUNE_INTERVAL is set, pruning removes dangling (untagged) images, unused volumes, and build cache. Containers and networks are not pruned. Pruning only runs when all composeflux-managed stacks are healthy and none have the composeflux.health.suspend=true label set.
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. Performs an immediate sync and force-reconciles all managed stacks. Useful when you update secrets in your secrets manager without making Git changes. See 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: The run daemon fetches secrets and deploys changes only when Git updates are detected or when a stack is unhealthy/missing. If you update secrets in your secrets manager without making Git changes, run composeflux sync manually to apply updated secrets. See
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
# Optional - Choose a secrets provider (omit to run without secrets):
# 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
# 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
# GIT_BRANCH: main
# Secrets Manager - Bitwarden (optional)
# 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
# Reconciliation & Pruning
# HEALTH_RECONCILE_INTERVAL: 5m # Proactive health check interval (disabled by default)
# PRUNE_INTERVAL: 24h # Periodic Docker resource prune interval (24h default, 0 to disable)
# 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
# - ~/.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:
- Leave
SECRETS_PROVIDERunset (or omit it entirely) - 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:
- Requires
SECRETS_PROVIDERto be set - 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 left empty (default), skips fetch and uses mounted key at
GIT_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=composeflux.managed=true"
# List all compose projects
docker compose ls