Run the quick start we publish, and it did not work #71

Merged
paulhitt merged 3 commits from 4-selfhost-smoke into main 2026-08-31 19:30:34 +00:00
paulhitt commented 2026-08-31 17:49:11 +00:00 (Migrated from gitlab.com)

Closes #4

Nothing in this repository ever ran the instructions it hands to self-hosters. A
job that does found two more faults on its first real run, on top of the one
it was written for.

The documented password broke the relay ~3 times in 4

SELF-HOSTING.md said openssl rand -base64 32 for POSTGRES_PASSWORD. That
goes into postgres://flamenet:<password>@db:5432/flamenet unencoded, and
base64 emits / or + 72.9% of the time (measured, 20k samples). A / ends
the URL authority:

Fatal error: NSURLErrorDomain Code=-1000
postgres://flamenet:ycP3Ecow1FjhKoOszG9X10u/xjqayh/yPAg5Z/Rku5Y=@db:5432/flamenet

Which reads like the database is unreachable, not like the password needs
escaping. Production never hit it — its password is hex, generated some way
other than the documented one.

The project already knew. .env.example carries a paragraph explaining
exactly this and saying to use -hex. The published quick start disagreed with
the file it tells people to copy — and the published one is what people follow.

.env.example was itself corrupted

In 8791321, a block of the FN_HOST_PORT comment was spliced into the middle
of the line pairing openssl rand -hex 32 with POSTGRES_PASSWORD — destroying
the only correct instruction in the tree — and left a bare POSTGRES_PASSWORD
line with no =. Restored from d019034.

Why it boots instead of linting

Both failures happen at up. docker compose config renders that file happily
with no web network and with a password that will not parse. A lint job
would have passed throughout both outages it exists to catch.

It asserts the landing page as well as /health: the compose file-s own header
promises a working install explains itself rather than answering 404, and a
missing Resources copy would leave health green.

Its own network name and compose project, never web — the deployment box has
a real web network and this script deletes what it creates.

Verified on the runner-s architecture

base64 password  → SELFHOST FAILED: no /health after 120s   (reproduces the crash)
hex password     → SELFHOST OK: boots and serves its landing page

Doc half: paulhitt/flamenet-e2e!4

Closes #4 Nothing in this repository ever ran the instructions it hands to self-hosters. A job that does found **two more faults on its first real run**, on top of the one it was written for. ### The documented password broke the relay ~3 times in 4 `SELF-HOSTING.md` said `openssl rand -base64 32` for `POSTGRES_PASSWORD`. That goes into `postgres://flamenet:<password>@db:5432/flamenet` **unencoded**, and base64 emits `/` or `+` **72.9% of the time** (measured, 20k samples). A `/` ends the URL authority: ``` Fatal error: NSURLErrorDomain Code=-1000 postgres://flamenet:ycP3Ecow1FjhKoOszG9X10u/xjqayh/yPAg5Z/Rku5Y=@db:5432/flamenet ``` Which reads like the database is unreachable, not like the password needs escaping. **Production never hit it** — its password is hex, generated some way other than the documented one. **The project already knew.** `.env.example` carries a paragraph explaining exactly this and saying to use `-hex`. The published quick start disagreed with the file it tells people to copy — and the published one is what people follow. ### `.env.example` was itself corrupted In `8791321`, a block of the `FN_HOST_PORT` comment was spliced into the middle of the line pairing `openssl rand -hex 32` with `POSTGRES_PASSWORD` — destroying the only correct instruction in the tree — and left a bare `POSTGRES_PASSWORD` line with no `=`. Restored from `d019034`. ### Why it boots instead of linting Both failures happen at `up`. `docker compose config` renders that file happily with no `web` network **and** with a password that will not parse. A lint job would have passed throughout both outages it exists to catch. It asserts the landing page as well as `/health`: the compose file-s own header promises a working install explains itself rather than answering 404, and a missing `Resources` copy would leave health green. Its own network name and compose project, never `web` — the deployment box has a real `web` network and this script deletes what it creates. ### Verified on the runner-s architecture ``` base64 password → SELFHOST FAILED: no /health after 120s (reproduces the crash) hex password → SELFHOST OK: boots and serves its landing page ``` Doc half: paulhitt/flamenet-e2e!4
paulhitt commented 2026-08-31 17:49:14 +00:00 (Migrated from gitlab.com)

mentioned in merge request flamenet-e2e!4

mentioned in merge request flamenet-e2e!4
paulhitt commented 2026-08-31 18:47:28 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 1fc5f8d1 - The self-hosting check cannot run on this runner

Compare with previous version

added 1 commit <ul><li>1fc5f8d1 - The self-hosting check cannot run on this runner</li></ul> [Compare with previous version](/paulhitt/flamenet-relay/-/merge_requests/8/diffs?diff_id=1995020974&start_sha=250a3bb63f1f52a3039141aa0907f6f97cba573d)
paulhitt commented 2026-08-31 18:47:40 +00:00 (Migrated from gitlab.com)

⚠️ Correcting the scope of this MR: the CI job is removed.

It failed with env: can-t execute bash, and the reason is worse than a missing
package. This project-s runner is a docker executor with:

executor = "docker"
image = "alpine:3.20"
privileged = false
volumes = ["/cache"]

So the job gets an alpine container with no bash, no docker CLI, and no path to
a daemon
. I wrote and tested the script against the host shell over ssh, which
is not what CI is — my mistake, and one the pipeline caught rather than me.

Wiring it up needs a runner change (privileged, a socket mount, or a shell
executor) on a machine that also serves production. That is the same class of
decision as #6 and not one to make on the way past.

🔴 Removed rather than left failing or made to skip. A job that always skips
is exactly the pattern I spent this afternoon deleting from the Android suite
(paulhitt/flamenet-messenger-android#4 — 18 tests reporting PASSED while running
nothing). Adding one here would be indefensible.

What still stands

The script works and has earned its place — on its first two runs it found the
missing docker network create web and the documented password that broke the
relay ~3 times in 4. It now says where it has to run:

ssh <box> "cd /srv/prod/messenger/src && ./Scripts/selfhost-smoke.sh"

⚠️ So this closes #4 only in the sense that the check exists and works. Nothing
boots the quick start in CI
remains true — it now has a named blocker rather
than an absence.

⚠️ **Correcting the scope of this MR: the CI job is removed.** It failed with `env: can-t execute bash`, and the reason is worse than a missing package. This project-s runner is a **docker executor** with: ``` executor = "docker" image = "alpine:3.20" privileged = false volumes = ["/cache"] ``` So the job gets an alpine container with no bash, **no docker CLI, and no path to a daemon**. I wrote and tested the script against the host shell over ssh, which is not what CI is — my mistake, and one the pipeline caught rather than me. Wiring it up needs a runner change (privileged, a socket mount, or a shell executor) on a machine that also serves production. That is the same class of decision as #6 and not one to make on the way past. 🔴 **Removed rather than left failing or made to skip.** A job that always skips is exactly the pattern I spent this afternoon deleting from the Android suite (paulhitt/flamenet-messenger-android#4 — 18 tests reporting PASSED while running nothing). Adding one here would be indefensible. ### What still stands The script works and has earned its place — on its first two runs it found the missing `docker network create web` **and** the documented password that broke the relay ~3 times in 4. It now says where it has to run: ``` ssh <box> "cd /srv/prod/messenger/src && ./Scripts/selfhost-smoke.sh" ``` ⚠️ So this closes #4 only in the sense that the check exists and works. *Nothing boots the quick start in CI* remains true — it now has a named blocker rather than an absence.
paulhitt commented 2026-08-31 18:48:22 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 10ef9519 - Regenerate /self-hosting: the password command people follow

Compare with previous version

added 1 commit <ul><li>10ef9519 - Regenerate /self-hosting: the password command people follow</li></ul> [Compare with previous version](/paulhitt/flamenet-relay/-/merge_requests/8/diffs?diff_id=1995022918&start_sha=1fc5f8d1d23e8a7ae3a005a4a18f9ffec18c1e61)
paulhitt commented 2026-08-31 19:30:35 +00:00 (Migrated from gitlab.com)

mentioned in commit f72653af8e

mentioned in commit f72653af8eb80f0a0657ba6ad1ae69066b92b037
paulhitt (Migrated from gitlab.com) merged commit f72653af8e into main 2026-08-31 19:30:35 +00:00
paulhitt commented 2026-08-31 20:22:38 +00:00 (Migrated from gitlab.com)

mentioned in merge request !9

mentioned in merge request !9
paulhitt commented 2026-09-09 18:59:24 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
Sign in to join this conversation.