Warden

Warden can clone and pull content/ for you, entirely from env vars: no manual git clone step, no credentials baked into a remote URL.

docker-compose.yml
yaml
services:
  warden:
    image: ghcr.io/hawkinslabdev/warden:latest
    env_file: .env
    volumes:
      - ./content:/app/content:Z
      - ./data:/app/data
.env
bash
GIT_ENABLED=true
GIT_URL=https://github.com/you/your-content.git
GIT_USERNAME=you
GIT_PASSWORD=your-token
GIT_CRON=*/5 * * * *

Off by default. If content/ isn't already a checkout, Warden clones GIT_URL into it on startup. Either way it then runs git pull --ff-only on the GIT_CRON schedule (standard 5-field cron expression) and the file watcher picks up the changes. A failed clone or pull logs a warning and never takes the site down. Needs write access to content/, so no :ro.

Don't quote the cron value in a compose environment: list; - GIT_CRON="*/5 * * * *" passes the quotes through. Use - GIT_CRON=*/5 * * * *.

GIT_USERNAME/GIT_PASSWORD are sent as an HTTP Basic auth header per git invocation, never written into the remote URL or .git/config. For a token-only host (e.g. GitHub PAT), set GIT_PASSWORD to the token and leave GIT_USERNAME as any non-empty value.

Only needed when content/ isn't the repo root:

txt
your-repo/
  content/
  theme/    # picked up automatically, no separate mount
.env
bash
GIT_ROOT=repo
DOCS_ROOT_PATH=repo/content
docker-compose.yml
yaml
volumes:
  - ./repo:/app/repo:Z