deeplo
Guides

Bootstrap configuration

Environment variables that control runtime settings — data directory, SSH, listening addresses, and GitHub integration.

deeplo has a two-layer configuration model:

LayerSourceControls
BootstrapEnvironment variables onlyAll runtime settings
ManagedYAML file (local disk or git repo)Hosts, repos, projects, triggers

The two layers are strictly separated. Managed config contains only structural deployment config — no paths, credentials, or runtime settings.

All bootstrap env vars use the DEEPLO_ prefix. Defaults prefer .yml, but explicit .yaml paths still work when you set them directly.


Environment variables

Config source

VariableDefaultDescription
DEEPLO_CONFIG_FILE/etc/deeplo/config.ymlPath to local config file (local mode)
DEEPLO_CONFIG_WATCHfalseWatch the mounted config file and reload when it changes (local mode)
DEEPLO_CONFIG_REPO_URLGit clone URL of config repo; switches to git mode when set
DEEPLO_CONFIG_REPO_BRANCHmainBranch to track (git mode)
DEEPLO_CONFIG_REPO_FILEconfig.ymlFile path within the repo (git mode)
DEEPLO_CONFIG_REPO_MODEpollHow config changes are detected: poll, webhook, or hybrid (git mode)
DEEPLO_CONFIG_REPO_INTERVAL60sHow often to check for config changes in poll or hybrid mode

Data and SSH

VariableDefaultDescription
DEEPLO_DATA_DIRData/cache root directory. Required.
DEEPLO_SSH_KEY_FILESSH private key for deploy hosts and git repo access. Required.
DEEPLO_SSH_USERdeployDefault SSH username on deploy hosts. hosts[].user overrides it per host.
DEEPLO_SSH_PORT22Default SSH port on deploy hosts. hosts[].port overrides it per host.
DEEPLO_SSH_KNOWN_HOSTSDEEPLO_DATA_DIR/known_hostsknown_hosts file for all SSH connections
DEEPLO_SSH_HOST_KEY_POLICYaccept-newaccept-new (TOFU — accept and remember new keys) or strict (require pre-existing entry)

HTTP and admin

VariableDefaultDescription
DEEPLO_WEBHOOK_PORT8080Webhook listener port.
DEEPLO_ADMIN_SOCKET/run/deeplo/deeplo.sockUnix socket path for the admin API (used by deeplo CLI).

Concurrency

VariableDefaultDescription
DEEPLO_MAX_WORKERS0 (= NumCPU)Maximum concurrent deploys across all hosts.
DEEPLO_HOST_PARALLEL1Maximum concurrent deploys per host.

Logging

VariableDefaultDescription
DEEPLO_LOG_LEVELinfoLog level: debug, info, warn, error.
DEEPLO_LOG_FORMATtextLog format: text or json.
DEEPLO_LOGS_PORTLog server port. Enables log serving when set.
DEEPLO_LOGS_PUBLIC_URLExternally reachable base URL used for GitHub "Details" links.
DEEPLO_LOG_RETENTION_DAYS14Log file retention in days (0 = keep forever).

GitHub integration

VariableDefaultDescription
DEEPLO_GITHUB_WEBHOOK_SECRET_FILEFile containing the GitHub webhook HMAC secret
DEEPLO_GITHUB_TOKEN_FILEFile containing a GitHub PAT; enables deployment reporting when set
DEEPLO_GITHUB_ENVIRONMENTOptional prefix for the GitHub environment name
DEEPLO_GITHUB_HOST_IN_ENVfalseSet to true to use <host>/<project> as the environment name (default: <project>)

Local config mode

If DEEPLO_CONFIG_REPO_URL is unset, deeplo reads the managed YAML config from DEEPLO_CONFIG_FILE (default /etc/deeplo/config.yml).

# docker-compose.yml
services:
  deeplo:
    image: ghcr.io/jancernik/deeplo:latest
    environment:
      DEEPLO_DATA_DIR: /var/lib/deeplo
      DEEPLO_SSH_KEY_FILE: /run/secrets/deploy_key
      DEEPLO_GITHUB_WEBHOOK_SECRET_FILE: /run/secrets/github_webhook_secret
    volumes:
      - ./config.yml:/etc/deeplo/config.yml:ro
      - ./data:/var/lib/deeplo
    secrets:
      - deploy_key
      - github_webhook_secret

Advanced: local config file watching (DEEPLO_CONFIG_WATCH)

DEEPLO_CONFIG_WATCH is an advanced convenience feature for local config mode. It tells deeplo to watch the managed config file on disk and reload it when the file changes instead of requiring a daemon restart after config edits.

Set DEEPLO_CONFIG_WATCH=true to enable it.

When a change is detected and the new config is valid:

  1. The in-memory config is replaced atomically.
  2. The poller is restarted with the updated repo list and intervals.
  3. Invalid configs are rejected and logged; the current config remains active.
environment:
  DEEPLO_CONFIG_WATCH: "true"

This is useful in development or when the config file is managed by a configuration management tool (Ansible, Puppet, etc.) that writes files directly to the host.

It is not the primary deployment path. If you just want a straightforward setup, mount a local config file and restart the daemon when you change it.


Git config mode

When DEEPLO_CONFIG_REPO_URL is set, deeplo fetches the managed config YAML from a git repository on startup. This is useful when you want the deployment config itself to be version-controlled and managed like any other file in a repo.

# docker-compose.yml
services:
  deeplo:
    image: ghcr.io/jancernik/deeplo:latest
    environment:
      DEEPLO_CONFIG_REPO_URL: git@github.com:yourorg/deeplo-config.git
      DEEPLO_CONFIG_REPO_BRANCH: main
      DEEPLO_CONFIG_REPO_FILE: config.yml
      DEEPLO_CONFIG_REPO_MODE: hybrid
      DEEPLO_DATA_DIR: /var/lib/deeplo
      DEEPLO_SSH_KEY_FILE: /run/secrets/deploy_key
      DEEPLO_GITHUB_WEBHOOK_SECRET_FILE: /run/secrets/github_webhook_secret
    volumes:
      - ./data:/var/lib/deeplo
    secrets:
      - deploy_key
      - github_webhook_secret

What happens on startup (git mode)

  1. ls-remote is run against DEEPLO_CONFIG_REPO_URL to get the branch tip SHA.
  2. The config repo is cloned as a bare mirror into DEEPLO_DATA_DIR/config/repos/ (or fetched if already present).
  3. The config file at DEEPLO_CONFIG_REPO_FILE is read from that exact commit.
  4. The config is parsed and validated.
  5. If valid, it is written to the last-known-good cache at DEEPLO_DATA_DIR/config/current.yml.

Automatic reload (git mode)

After startup, a config watcher detects changes to the config repo and reloads automatically. How it detects changes is controlled by DEEPLO_CONFIG_REPO_MODE:

ModeBehaviour
poll (default)Checks for new commits every DEEPLO_CONFIG_REPO_INTERVAL (default 60s)
webhookReloads immediately when a push to the config repo arrives at /webhooks/github
hybridBoth — webhook for instant reload, poll as a safety net

When a new commit is detected and the updated config is valid:

  1. The in-memory config is replaced atomically — all subsequent deploys use the new values.
  2. The poller is restarted so new repos, intervals, and trigger modes take effect immediately.
  3. The webhook route (/webhooks/github) always reads the current config, so newly added webhook-mode repos are handled without a daemon restart.

Changing a repo's trigger_mode or poll_interval reloads the runtime trigger behavior only. It does not by itself redeploy all projects. When a repo is switched from webhook-only to poll or hybrid mode, deeplo seeds the current branch tip as the poll baseline so the reload does not create an artificial first-poll deploy storm.

Invalid configs are rejected and logged; the current config remains active.

Required env vars for git mode

VarReason
DEEPLO_CONFIG_REPO_URLWhere to fetch the config from
DEEPLO_DATA_DIRWhere to store the local mirror and cache
DEEPLO_SSH_KEY_FILESSH key for fetching the config repo and deploying to target hosts

DEEPLO_SSH_KNOWN_HOSTS defaults to DEEPLO_DATA_DIR/known_hosts. With DEEPLO_SSH_HOST_KEY_POLICY=accept-new (default), host keys are accepted automatically on first connection and stored there.


Last-known-good cache (git mode)

When DEEPLO_CONFIG_REPO_URL is set, deeplo maintains a last-known-good cache:

DEEPLO_DATA_DIR/config/
  current.yml     validated managed config from last successful fetch
  meta.json       source URL, branch, commit SHA, fetch timestamp
  repos/          bare git mirror of the config repo
SituationResult
Fetch succeeds, config validCache updated, new config used
Fetch fails, valid cache existsWarning logged, cached config used
Fetch succeeds, config invalidCache not updated, current config kept
Fetch fails, no cacheStartup fails with a clear error
Reload: fetch failsWarning logged, current in-memory config kept
Reload: config invalidError logged, current in-memory config kept

Bad config pushes cannot take down a running daemon — the previous valid config remains active until a valid one is pushed.


Shared SSH key

deeplo uses DEEPLO_SSH_KEY_FILE for both:

  • fetching the managed config repo in git mode
  • fetching watched repos
  • deploying to target hosts over SSH

If you need different credentials, that is outside the current product scope. The bootstrap layer keeps the SSH auth story intentionally simple.

On this page