Skip to content

fix(lemmy): the bundle starts, and the generated admin can log in (lemmy 1.0.4) - #511

Merged
kh0pper merged 2 commits into
mainfrom
fix/lemmy-starts-main
Oct 17, 2026
Merged

kh0pper merged 2 commits into
mainfrom
fix/lemmy-starts-main

Conversation

@kh0pper

@kh0pper kh0pper commented Oct 16, 2026

Copy link
Copy Markdown
Owner

This replaces #510. #510 was stacked on #504, which has since been squash-merged to main (3a5c7be, together with #505). This PR has the same two Lemmy commits, rebased onto main with nothing from #504 repeated. The tree matches #510's head, so #510's live proof and reviews still apply. The details are in #510's description and comment; here is the summary.

Why Lemmy never started (checked against the pinned images)

  1. The entrypoint ran exec /app/lemmy. dessalines/lemmy:0.19.17 has no /app: the binary is /usr/local/bin/lemmy_server, and the image runs as uid 1000.
  2. The entrypoint wrote /config/config.hjson into ./config, which was mounted :ro.
  3. Both health checks used wget, and neither image ships it (both have curl). Lemmy never became healthy, so lemmy-ui never started.
  4. pict-rs runs as uid 991 on a host folder that the Docker daemon creates as root.
  5. Config keys that 0.19 ignores (federation.enabled, captcha) and pict-rs 0.4 names that 0.5 ignores did nothing. tls_enabled: false gave http:// actor ids behind Caddy's https.

Fix

  • Entrypoint: writes a mode-600 config into the container's own /tmp at every start, then exec lemmy_server.
  • Hostname and secrets: these reach the script only through the environment. The hostname is checked to be a bare lowercase name, and a test runs the entrypoint's real pattern.
  • Health checks: use curl.
  • Data: Postgres and pict-rs data live in the project's own volumes.
  • Config: holds only keys that 0.19 reads, with tls_enabled: true.
  • Removed: LEMMY_FEDERATION_ENABLED and LEMMY_OPEN_REGISTRATION. These are site settings in 0.19.
  • backup.sh: fails loudly instead of writing an empty archive.
  • Version and registry: manifest 1.0.4, registry and skill ledger rebuilt.

Live proof (scratch home only; details in #510)

  • Setup:
    • All data paths were in a scratch directory, and the run refused to start if any of them were under ~/.crow*.
    • The compose project had a unique name, used its own network, and published loopback-only ports.
    • An out-of-process deadman would have torn everything down.
    • The run was registered in the box schedule.
  • Install path: the gateway's own install code ran in this order: generate secrets, save to the keychain first, write .env, then run checkBundleCompose, which returned {"valid":true}.
  • Result:
    • All 4 containers came up healthy, and /api/v3/site returned 200.
    • Logging in with the admin password read back from the keychain returned a JWT with admin: true. A wrong password returned 401.
    • A pict-rs upload worked.
    • The secret did not appear in argv or the logs.
    • After a restart, the admin was not created again.
  • Teardown: nothing was left behind.

Follow-ups (not fixed here)

  • lemmy-ui does not proxy the API (404). The public site needs a split route to lemmy:8536, which caddy_add_federation_site can't express yet.
  • The host-run MCP server can't resolve the default LEMMY_URL=http://lemmy:8536. The sibling federated bundles have the same pattern.

Licensing

  • Lemmy, lemmy-ui and pict-rs are AGPL-3.0 (pict-rs is AGPL-3.0-only). Postgres uses the PostgreSQL License.
  • They run as unmodified, separate containers, so Crow's MIT code is not affected.
  • A hosted Crow offering that runs Lemmy for others must offer them the source of the Lemmy version it runs (AGPL §13).

Tests

https://claude.ai/code/session_01N9fXzvNy8rCEArj1y5p6fp

…mmy 1.0.4)

The Lemmy bundle never started on the pinned images:
- the entrypoint ran /app/lemmy; dessalines/lemmy:0.19.17 ships
  /usr/local/bin/lemmy_server (the image's own entrypoint);
- it wrote its config into ./config, mounted read-only, as uid 1000;
- both health checks called wget, which neither the lemmy nor the lemmy-ui
  image has, so lemmy never turned healthy and lemmy-ui never started;
- pict-rs runs as uid 991 and got a host folder the Docker daemon creates
  as root.

Now the entrypoint writes a mode-600 config into the container's own /tmp at
every start and execs lemmy_server; the hostname reaches the script through
the environment and is checked (bare hostname only) before use; health checks
use curl; Postgres and pict-rs data live in this compose project's own
volumes, so uninstall with delete data removes both; the config holds only
keys Lemmy 0.19 reads (tls_enabled true because Caddy serves https);
pict-rs limits use the 0.5 key names; LEMMY_FEDERATION_ENABLED and
LEMMY_OPEN_REGISTRATION are gone (site settings in 0.19). The generated
LEMMY_ADMIN_PASSWORD (keychain) still reaches Lemmy's first-start setup only
through the environment.

Docs: lemmy-ui does not proxy the API (checked live: 404), so the notes,
skill and post-install text say the public site must split /api, /pictrs,
/feeds, /nodeinfo, /.well-known and ActivityPub traffic to lemmy:8536.
Licensing note added (AGPL-3.0 Lemmy/lemmy-ui/pict-rs, separate containers).

Claude-Session: https://claude.ai/code/session_01N9fXzvNy8rCEArj1y5p6fp
…tead of writing an empty archive

Review follow-ups: the hostname must be bare and lowercase with no leading or
trailing dot, colon or dash and no empty label; a test runs the entrypoint's own
case pattern against good and bad values. backup.sh refuses when pict-rs is not
running or its archive is empty.

Claude-Session: https://claude.ai/code/session_01N9fXzvNy8rCEArj1y5p6fp
@kh0pper
kh0pper merged commit df435ee into main Oct 17, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant