A release that mounted app.ini directly as a read-only swarm config leaves a 0-byte placeholder at
/etc/gitea/app.ini in the reattached config volume on upgrade; the original seed guard (! -f) treated
that as present and skipped, so Gitea booted the install wizard on an empty config (/api/v1/version
404). Guard on ! -s (missing OR empty) so the rendered config is seeded; bump DOCKER_SETUP_SH_VERSION
so the corrected entrypoint deploys (immutable swarm configs).
Gitea 1.24+ (re)generates and SAVES the [oauth2] JWT secret to /etc/gitea/app.ini at
LoadCommonSettings. With app.ini mounted directly as a read-only swarm config this fails fatally
(open /etc/gitea/app.ini: read-only file system) on a warm reattach/redeploy, crash-looping the
container before any DB migration. Mount the rendered config at /etc/gitea/app.ini.init (read-only)
and seed it once into the writable config volume via docker-setup.sh, so Gitea owns a writable
/etc/gitea/app.ini. Bumps DOCKER_SETUP_SH_VERSION so the new entrypoint actually deploys.
Add an opt-in compose.lfs.yml that mounts the lfs_jwt_secret secret and
enables GITEA_LFS_START_SERVER for plain gitea (forgejo already bundles
LFS). Emit LFS_JWT_SECRET in app.ini whenever the LFS server is on so the
JWT secret is stable across redeploys instead of being regenerated on
every restart (app.ini is a read-only config mount).
Bump version 3.5.2 -> 3.6.0.