Polling Local Filesystem Repositories¶
Some stacks cannot be deployed without a running SCM available (e.g. a self-hosted Gitea/Forgejo instance that should be deployed via doco-cd (hence a chicken-and-egg problem), or a stack that is deployed from a local Git repository that is not hosted on any remote SCM).
For these cases, doco-cd can poll a Git repository that already lives on the local filesystem, e.g. bind-mounted into the container, instead of a remote host.
This reuses the exact same polling mechanism, deployment pipeline and auto-discovery used for remote Git repositories - the only difference is the url scheme.
Configuration¶
Mount the local Git repository into the doco-cd container (read-only is recommended, doco-cd never writes to it - it clones into its own working directory), then reference it in a poll configuration using either an absolute path or a file:// URL:
services:
app:
container_name: doco-cd
image: ghcr.io/kimdre/doco-cd:latest
restart: unless-stopped
environment:
TZ: Europe/Berlin
POLL_CONFIG: |
- source: git
url: file:///local-repos/my-app # Or use `url: /local-repos/my-app`
reference: main
interval: 60s
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- data:/data
- /host/path/to/my-app.git:/local-repos/my-app:ro
volumes:
data:
See Poll Settings for the full list of poll configuration fields.
How it works¶
urlmust be an absolute path inside the container (e.g./local-repos/my-app) or the equivalentfile://URL (e.g.file:///local-repos/my-app).- Both regular repositories (with a
.gitdirectory) and bare repositories (e.g.my-app.git) are supported, as are linked worktrees and submodule checkouts that use a.gitfile. referencebehaves exactly like it does for remote Git repositories: a branch name, tag name, or commit SHA.- On every poll interval, doco-cd checks the local repository for new commits on
referenceand, if changed, deploys them using the same pipeline as remote Git polling (including.doco-cd.yml/.doco-cd.*.ymldiscovery and auto-discovery). - No credentials are needed or used for local repositories.
- In addition to interval-based polling, doco-cd watches the local repository's git directory for changes and triggers a deployment check immediately when new commits land, without waiting for the next interval. This is enabled by default; set
watch: falseto disable it and rely onintervalonly. Setinterval: 0(withwatchleft enabled) to rely on the watcher exclusively, with no periodic fallback polling at all.
Webhook-triggered local mirrors¶
Local repositories do not emit webhooks themselves. If the repository is a local mirror of a GitHub, GitLab, or Forgejo repository, its SCM webhook can trigger deployment from the local mirror instead.
Configure an explicit SOURCE_URL_REWRITES rule that transforms the SCM clone URL into the mounted local path:
environment:
SOURCE_URL_REWRITES: |
https://forgejo.example.com/: file:///local-repos/
For example, a webhook whose clone URL is https://forgejo.example.com/org/my-app.git then deploys from file:///local-repos/org/my-app.git. For safety, doco-cd rejects a file:// clone URL supplied directly by a webhook payload; it must result from a configured rewrite.
Limitations¶
- Local repositories have no native webhook source. Webhook-triggered deployments require an SCM webhook and an explicit
SOURCE_URL_REWRITESrule as shown above. - No commit status is posted back to an SCM, since there is none to post to.
- Shallow clones are not supported for local repositories:
git_depthandGIT_CLONE_DEPTHare ignored and the repository is always cloned in full. This avoids network transfer, but can still cost disk I/O and storage for large histories. - The change watcher detects updates to top-level branch refs and
packed-refs. Nested branch names (e.g.release/1.0, which git stores under arefs/heads/release/subdirectory) are only detected if that subdirectory already existed when the watcher started; if not, changes to that branch are picked up on the next poll interval instead of immediately. Non-nested branch names (e.g.main,release-1.0) are unaffected. - If the watcher fails to start, is disabled (
watch: false), or closes unexpectedly whileinterval: 0, doco-cd falls back to a 24h safety-net poll interval instead of never polling again.