deployment templates for lichen
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

add override.yml: deploy custom lichen-server binary via ansible

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.

notplants 42d00c64 31cb3311

+128
+39
ansible/README.md
··· 63 63 | `lichen_deploy_dir` | `/srv/lichen` | target directory on the server | 64 64 | `lichen_rust_log` | `info` | `RUST_LOG` for the container | 65 65 66 + ## Deploy a custom binary 67 + 68 + `override.yml` uploads a locally-built `lichen-server` binary to the server's 69 + `bin/` directory and restarts the app container. The compose stack's 70 + entrypoint prefers `/opt/lichen-bin/lichen-server` over the image-bundled 71 + binary when present, so no other changes are needed. 72 + 73 + ### Build 74 + 75 + Build against `x86_64-unknown-linux-musl` so the binary runs in the Alpine 76 + image. From the lichen source tree: 77 + 78 + ```bash 79 + cargo build --release --target x86_64-unknown-linux-musl \ 80 + --bin lichen-server --features "atproto git" 81 + ``` 82 + 83 + (see the `/lichen-mod` Claude skill for details). 84 + 85 + ### Deploy 86 + 87 + ```bash 88 + ansible-playbook -i inventory.yml override.yml \ 89 + --extra-vars "lichen_binary_src=../../../target/x86_64-unknown-linux-musl/release/lichen-server" 90 + ``` 91 + 92 + The path is relative to the `ansible/` directory. Absolute paths also work. 93 + 94 + ### Revert 95 + 96 + ```bash 97 + ansible-playbook -i inventory.yml override.yml \ 98 + --extra-vars "lichen_override_revert=true" 99 + ``` 100 + 101 + Removes the override file and restarts so the image's built-in binary takes 102 + over again. 103 + 66 104 ## Backups (optional) 67 105 68 106 `backup.yml` installs Borg + systemd timers that back up the `lichen_data` ··· 124 162 ├── ansible.cfg 125 163 ├── deploy.yml # install docker + deploy from scratch 126 164 ├── update.yml # pull latest image + restart 165 + ├── override.yml # upload a custom binary (or revert) 127 166 ├── backup.yml # install borg + timers (optional) 128 167 ├── inventory.example.yml 129 168 ├── roles/
+89
ansible/override.yml
··· 1 + --- 2 + # Deploy a locally-built lichen-server binary as a runtime override. 3 + # 4 + # The compose stack bind-mounts ./bin:/opt/lichen-bin:ro and the entrypoint 5 + # prefers /opt/lichen-bin/lichen-server over the image-bundled binary when 6 + # present. This playbook uploads that file and restarts the app container. 7 + # 8 + # usage: 9 + # # upload a custom binary (built for x86_64-unknown-linux-musl) 10 + # ansible-playbook -i inventory.yml override.yml \ 11 + # --extra-vars "lichen_binary_src=./target/x86_64-unknown-linux-musl/release/lichen-server" 12 + # 13 + # # revert to the image's built-in binary 14 + # ansible-playbook -i inventory.yml override.yml \ 15 + # --extra-vars "lichen_override_revert=true" 16 + 17 + - name: Deploy or revert a custom lichen-server binary 18 + hosts: all 19 + become: true 20 + vars: 21 + lichen_deploy_dir: /srv/lichen 22 + lichen_override_revert: false 23 + pre_tasks: 24 + - name: Require exactly one of lichen_binary_src or lichen_override_revert 25 + assert: 26 + that: 27 + - (lichen_binary_src is defined) or lichen_override_revert | bool 28 + - not ((lichen_binary_src is defined) and lichen_override_revert | bool) 29 + fail_msg: >- 30 + Pass --extra-vars "lichen_binary_src=<path>" to deploy a binary, 31 + OR --extra-vars "lichen_override_revert=true" to revert. 32 + - name: Verify the local binary exists 33 + stat: 34 + path: "{{ lichen_binary_src }}" 35 + register: local_bin 36 + delegate_to: localhost 37 + become: false 38 + when: not lichen_override_revert | bool 39 + - name: Fail if the local binary is missing 40 + fail: 41 + msg: "lichen_binary_src={{ lichen_binary_src }} does not exist on this workstation" 42 + when: 43 + - not lichen_override_revert | bool 44 + - not local_bin.stat.exists 45 + - name: Check that the deployment exists 46 + stat: 47 + path: "{{ lichen_deploy_dir }}/docker-compose.yml" 48 + register: compose_stat 49 + - name: Fail if the deployment hasn't been set up yet 50 + fail: 51 + msg: "{{ lichen_deploy_dir }}/docker-compose.yml not found — run deploy.yml first." 52 + when: not compose_stat.stat.exists 53 + 54 + tasks: 55 + - name: Ensure bin/ exists on the server 56 + file: 57 + path: "{{ lichen_deploy_dir }}/bin" 58 + state: directory 59 + mode: "0755" 60 + 61 + - name: Upload custom binary 62 + copy: 63 + src: "{{ lichen_binary_src }}" 64 + dest: "{{ lichen_deploy_dir }}/bin/lichen-server" 65 + mode: "0755" 66 + when: not lichen_override_revert | bool 67 + 68 + - name: Remove custom binary 69 + file: 70 + path: "{{ lichen_deploy_dir }}/bin/lichen-server" 71 + state: absent 72 + when: lichen_override_revert | bool 73 + 74 + - name: Restart the app container to pick up the change 75 + command: docker compose restart app 76 + args: 77 + chdir: "{{ lichen_deploy_dir }}" 78 + changed_when: true 79 + 80 + - name: Wait for the app to report healthy 81 + command: docker compose ps --format '{{ "{{.Health}}" }}' app 82 + args: 83 + chdir: "{{ lichen_deploy_dir }}" 84 + register: health 85 + until: "'healthy' in health.stdout" 86 + retries: 12 87 + delay: 5 88 + changed_when: false 89 + failed_when: false