commits
- docker-compose.staging.yml: staging service on port 9001
- Caddyfile: staging.lichen.page proxied to staging:9001
- override.yml: lichen_binary_dir variable (bin or staging-bin)
- removed separate docker-compose-staging directory
- docker-compose-staging/: app-only stack on port 9001, no Caddy
- Caddyfile: staging.lichen.page and *.staging.lichen.page proxy to localhost:9001
- ansible role: lichen_compose_src and lichen_compose_files variables
Caddy now serves files from each site's dist/ directory for normal
visitors, only proxying to the Rust app for CMS/auth/API/websocket
paths. Falls back to the app if no static file is found.
- docker-compose: pass DEFAULT_STORAGE_LIMIT env var to container
- entrypoint: write default_storage_limit to lichen.toml on first run
- env.j2: template the new var from ansible inventory
- inventory.example: add lichen_default_storage_limit example ("5MB")
override.yml uploads a locally-built binary to {{ deploy_dir }}/bin/lichen-server
and restarts the app container. The compose entrypoint already prefers that
path over the image-bundled binary when present, so no other changes are
needed to take effect.
Usage:
# deploy
ansible-playbook override.yml --extra-vars \
"lichen_binary_src=./target/x86_64-unknown-linux-musl/release/lichen-server"
# revert to stock
ansible-playbook override.yml --extra-vars \
"lichen_override_revert=true"
Pre-tasks enforce exactly one mode and that the local binary exists before
uploading. Post-upload waits for healthcheck to go green so a bad build
fails loudly instead of silently.
README adds a "Deploy a custom binary" section with the build command.
backup.yml (opt-in) installs borg, uploads the borgbase SSH key,
initializes the repo on first run if empty, and registers two systemd
timers:
- lichen-backup.timer (daily at 03:00 by default) — borg create +
prune + compact against the lichen_data docker volume
- lichen-borg-check.timer (first Sunday of the month) — borg check
--verify-data to catch archive corruption early
No app downtime — backups run hot against the live volume. Site data is
git-managed with atomic renames, so a mid-commit archive restores cleanly.
Retention defaults: 7 daily / 4 weekly / 6 monthly. Variables are in the
playbook header; overridable via group_vars.
Also adds inventory.yml to the submodule .gitignore to keep operators'
real inventories out of the repo.
community.general.yaml callback was removed in community.general 12.0.0.
ansible-core 2.13+ supports the same output via callback_result_format=yaml
on the built-in default callback.
deploy.yml sets up a fresh server: installs docker via get.docker.com,
syncs the docker-compose reference files to /srv/lichen, renders an
.env from inventory vars, pulls images, and waits for the app health
check to turn green.
update.yml targets an existing deployment: re-syncs the compose files
(picking up any upstream changes), optionally uploads a locally-built
custom binary from ../docker-compose/bin/lichen-server, pulls the
latest image, and restarts the stack.
Two roles (docker + lichen) split the work. The compose/Caddyfile/
entrypoint are not duplicated — Ansible ships the existing
docker-compose/ files via copy.
Simple VPS deployment: lichen + caddy with on-demand TLS.
Supports overriding the binary by dropping a custom build
into bin/ — entrypoint detects and uses it automatically.
override.yml uploads a locally-built binary to {{ deploy_dir }}/bin/lichen-server
and restarts the app container. The compose entrypoint already prefers that
path over the image-bundled binary when present, so no other changes are
needed to take effect.
Usage:
# deploy
ansible-playbook override.yml --extra-vars \
"lichen_binary_src=./target/x86_64-unknown-linux-musl/release/lichen-server"
# revert to stock
ansible-playbook override.yml --extra-vars \
"lichen_override_revert=true"
Pre-tasks enforce exactly one mode and that the local binary exists before
uploading. Post-upload waits for healthcheck to go green so a bad build
fails loudly instead of silently.
README adds a "Deploy a custom binary" section with the build command.
backup.yml (opt-in) installs borg, uploads the borgbase SSH key,
initializes the repo on first run if empty, and registers two systemd
timers:
- lichen-backup.timer (daily at 03:00 by default) — borg create +
prune + compact against the lichen_data docker volume
- lichen-borg-check.timer (first Sunday of the month) — borg check
--verify-data to catch archive corruption early
No app downtime — backups run hot against the live volume. Site data is
git-managed with atomic renames, so a mid-commit archive restores cleanly.
Retention defaults: 7 daily / 4 weekly / 6 monthly. Variables are in the
playbook header; overridable via group_vars.
Also adds inventory.yml to the submodule .gitignore to keep operators'
real inventories out of the repo.
deploy.yml sets up a fresh server: installs docker via get.docker.com,
syncs the docker-compose reference files to /srv/lichen, renders an
.env from inventory vars, pulls images, and waits for the app health
check to turn green.
update.yml targets an existing deployment: re-syncs the compose files
(picking up any upstream changes), optionally uploads a locally-built
custom binary from ../docker-compose/bin/lichen-server, pulls the
latest image, and restarts the stack.
Two roles (docker + lichen) split the work. The compose/Caddyfile/
entrypoint are not duplicated — Ansible ships the existing
docker-compose/ files via copy.