@@ -98,7 +98,7 @@ write_files:
9898 respond "no site configured for {host}" 404
9999 }
100100
101- - path: /var/lib/workloads/forgejo/app.ini
101+ - path: /var/lib/workloads/forgejo/app.ini.template
102102 content: |
103103 APP_NAME = Forgejo
104104 RUN_USER = git
@@ -231,11 +231,19 @@ write_files:
231231 /etc/workloads.d/alloy.toml
232232 fi
233233
234- # Caddyfile + app.ini are written by write_files (substituted at ISO build
235- # time), so they're already in place — just ensure the dirs exist for
236- # workloadctl's volume bind-mounts and the data disk mount points.
234+ # Caddyfile is written by write_files (substituted at ISO build time).
235+ # app.ini.template is also written by write_files. The live app.ini is
236+ # promoted from the template here only if Forgejo has not yet been
237+ # initialized (INSTALL_LOCK absent or false). On instance-id rotation
238+ # (e.g. a TOML edit that rebundles the ISO), cloud-init re-runs
239+ # write_files but must NOT clobber an initialized app.ini: that file
240+ # holds INSTALL_LOCK=true, SECRET_KEY, and INTERNAL_TOKEN — losing it
241+ # silently resets Forgejo to the web installer and breaks git push.
237242 install -d /var/lib/workloads/caddy
238243 install -d /var/lib/workloads/forgejo
244+ if ! grep -q 'INSTALL_LOCK = true' /var/lib/workloads/forgejo/app.ini 2>/dev/null; then
245+ cp /var/lib/workloads/forgejo/app.ini.template /var/lib/workloads/forgejo/app.ini
246+ fi
239247
240248 # Per-workload data dirs under each workload's home (on the system
241249 # disk btrfs for caddy; on data.qcow2 for forgejo via the
0 commit comments