lotus-land-story: run docket
Mirrors the pro-tacts deploy: container on the docker network with a
data volume, served from a tsnet-bound Caddy site. Requires
docket.fastmail_tokens in the sops vars — one Fastmail API token per
login — before the playbook can run.

Assisted-by: GLM-5.3 via pi
change mvqqtzkqqspmlwsklnmlnooroylwtoow
commit 08440ef466e25366f7b01a1a39fb9f576241cb40
author Alpha Chen <alpha@kejadlen.dev>
date
parent tvzktqup
diff --git a/host_vars/lotus-land-story.yml b/host_vars/lotus-land-story.yml
index cbfb5c9..2330c7f 100644
--- a/host_vars/lotus-land-story.yml
+++ b/host_vars/lotus-land-story.yml
@@ -4,6 +4,7 @@ versions:
   cadvisor:         0.60.6
   caddy:            2.11.6-2026.10.03 # don't forget to update caddy-kejadlen first!
   calibre_web:      0.6.26-ls383
+  docket:           latest # TODO Pin the version once we're not in active development anymore
   dockhand:         v1.0.50
   gamja:            caf6e99
   gitea:            1.26.2
diff --git a/lotus-land-story/docket.yml b/lotus-land-story/docket.yml
new file mode 100644
index 0000000..2f69769
--- /dev/null
+++ b/lotus-land-story/docket.yml
@@ -0,0 +1,62 @@
+# https://github.com/kejadlen/docket
+- name: Set up docket
+  hosts: lotus-land-story
+  vars:
+    version: "{{ versions.docket }}"
+  tasks:
+
+    - name: Create docket data directory
+      ansible.builtin.file:
+        path: /mnt/lotus-land-story/docket
+        state: directory
+        mode: "0755"
+
+    - name: Create docket secrets directory
+      ansible.builtin.file:
+        path: /mnt/lotus-land-story/docket/secrets
+        state: directory
+        mode: "0700"
+
+    # Docket reads tokens by token-file, never inline in the config.
+    - name: Write Fastmail tokens
+      ansible.builtin.copy:
+        content: "{{ item.value }}"
+        dest: "/mnt/lotus-land-story/docket/secrets/{{ item.key }}"
+        mode: "0600"
+      loop: "{{ docket.fastmail_tokens | dict2items }}"
+      loop_control:
+        label: "{{ item.key }}"
+      no_log: true
+
+    - name: Write docket config
+      ansible.builtin.copy:
+        # Binds wide because Caddy reaches it over the docker network.
+        content: |
+          bind "0.0.0.0:3000"
+          database "/data/docket.db"
+          {% for name in docket.fastmail_tokens | sort %}
+          credential "{{ name }}" token-file="/run/credentials/docket/{{ name }}"
+          {% endfor %}
+        dest: /mnt/lotus-land-story/docket/docket.kdl
+        mode: "0644"
+
+    - name: Run docket
+      community.docker.docker_container:
+        name: docket
+        image: ghcr.io/kejadlen/docket:{{ version }}
+        pull: always
+        env:
+          DOCKET_CONFIG: /data/docket.kdl
+        volumes:
+          - /mnt/lotus-land-story/docket:/data
+          - /mnt/lotus-land-story/docket/secrets:/run/credentials/docket:ro
+        networks:
+          - name: lotus_land_story
+        restart_policy: unless-stopped
+        state: started
+
+  handlers:
+    - name: Import restarts
+      ansible.builtin.import_tasks: restarts.yml
+
+# vim: ft=yaml.ansible
diff --git a/lotus-land-story/main.yml b/lotus-land-story/main.yml
index dab3384..15678e2 100644
--- a/lotus-land-story/main.yml
+++ b/lotus-land-story/main.yml
@@ -73,5 +73,6 @@
 - import_playbook: otel.yml        # noqa: name[play]
 - import_playbook: quire.yml       # noqa: name[play]
 - import_playbook: pro-tacts.yml   # noqa: name[play]
+- import_playbook: docket.yml      # noqa: name[play]
 
 # vim: ft=yaml.ansible
diff --git a/lotus-land-story/templates/Caddyfile b/lotus-land-story/templates/Caddyfile
index 4c16f78..ea887ed 100644
--- a/lotus-land-story/templates/Caddyfile
+++ b/lotus-land-story/templates/Caddyfile
@@ -138,6 +138,11 @@ ketchup {
 	}
 }
 
+docket {
+	import tsauth docket
+	reverse_proxy docket:3000
+}
+
 ### Family
 
 books {