Audited: the mnfst/manifest self-hosting/Docker surface (app v6.18.0, clone @126bd7ff8) against the docs at 9eebdf8. Scoped nightly rotation, topic "self-hosting with Docker (install, upgrade, backup)". Window: the full feature surface (docker/install.sh, docker/docker-compose.yml, docker/.env.example, docker/Dockerfile, the image-signing CI, telemetry) plus the recent self-hosting PRs #2565, #2591, #2693, #1649, #1777, #1785.
Page in scope: self-hosted.mdx (the only page these findings may target).
Findings
1 · [OBSOLETE] The "Exposing on the LAN" steps tell you to edit a compose line that no longer exists, and any compose edit is wiped by the next upgrade. The real knob is one line in .env.
Page: https://manifest.build/docs/self-hosted (Exposing on the LAN)
What actually happens:
- You follow the "Exposing on the LAN" steps and open the compose file to change the port binding exactly as the page instructs.
- The exact text the page tells you to find and replace is not there, so you cannot complete the step and LAN access stalls.
- If you improvise your own edit to open the port, LAN access works only until the next upgrade: the upgrade the same page recommends rewrites the compose file and silently drops the dashboard back to host-only, with no error or warning.
- There is a one-line setting that opens LAN access and survives every upgrade, but the page never mentions it.
The behavioral claim is fine: the dashboard does bind to 127.0.0.1 by default. Only the "how to change it" instruction is broken.
Options:
- Rewrite the step to set
HOST_BIND_ADDRESS=0.0.0.0 in .env and drop the compose edit. Recommended. (Introduces HOST_BIND_ADDRESS into the prose, so the page's Core env-var table gains its row and the BIND_ADDRESS note is re-pointed; suggested wording below. A matching row in the environment-variables reference is needed to keep the two in sync; that is tracked in the backlog, not part of this finding.)
- Keep the compose edit, but fix the search string to the real templated line and warn that the edit is lost on
--upgrade unless moved to .env.
- Document both:
.env HOST_BIND_ADDRESS as primary, the compose edit as an advanced override.
Suggested wording (option 1)
Replacement for the "Exposing on the LAN" <Steps> block:
## Exposing on the LAN
By default the compose file binds port 2099 to `127.0.0.1` only. The dashboard is reachable from the host but not from other machines on the network. To expose it on the LAN:
<Steps>
<Step title="Bind to all interfaces">
In `.env`, set:
```bash
HOST_BIND_ADDRESS=0.0.0.0
```
The compose file reads `${HOST_BIND_ADDRESS:-127.0.0.1}` for the host side of the port mapping, so one line opens it up with no YAML edit. Editing `docker-compose.yml` by hand does not survive an upgrade; `.env` does.
</Step>
<Step title="Set BETTER_AUTH_URL">
In `.env`, set `BETTER_AUTH_URL` to the host you'll reach the dashboard on, e.g. `http://192.168.1.20:2099` or `https://manifest.mydomain.com`. This must match the URL in the browser or Better Auth will reject the login with "Invalid origin".
</Step>
<Step title="Apply">
```bash
docker compose up -d
```
</Step>
</Steps>
New Core env-var table row (insert below the PORT row):
| `HOST_BIND_ADDRESS` | No | `127.0.0.1` | Host interface the dashboard port binds to. Set `0.0.0.0` to reach it over the LAN |
Re-pointed BIND_ADDRESS sentence in the <Note>:
`BIND_ADDRESS` is likewise set by the image (`0.0.0.0`, so the container is reachable through Docker's port mapping); control host exposure with `HOST_BIND_ADDRESS` in `.env`, not this variable.
Evidence (for the agent)
- Doc:
self-hosted.mdx:208 — change the portsline from"127.0.0.1:2099:2099"to"2099:2099".; intro Note self-hosted.mdx:17; the BIND_ADDRESS Note self-hosted.mdx:326.
- Compose:
docker/docker-compose.yml:50 — ports line "${HOST_BIND_ADDRESS:-127.0.0.1}:${HOST_PORT:-${PORT:-2099}}:${PORT:-2099}"; the literal 127.0.0.1:2099:2099 string is absent (grep clean at HEAD). Header docker-compose.yml:30-32 — "To expose on the LAN, set HOST_BIND_ADDRESS=0.0.0.0 and update BETTER_AUTH_URL in .env". docker/.env.example:28 — # HOST_BIND_ADDRESS=0.0.0.0.
- Upgrade wipes compose edits:
docker/install.sh:240-251 (--upgrade downloads and atomically replaces docker-compose.yml); .env is never modified by the installer.
- Version pin: the
HOST_BIND_ADDRESS/HOST_PORT ports template first shipped in released tag manifest@6.18.0 (absent from 6.17.1 and earlier), same release that added the manifest_request_recordings volume (PR #2565).
- Impact: a user following the LAN steps cannot find the line to edit; if they improvise a compose edit, the documented upgrade silently drops them back to localhost.
Reply with the finding number and the chosen option
(e.g. "3 → option 2", or "3: other idea, let's discuss").
PRs are then made manually with the agent, never by the harness.
Rejected findings: reply "N → reject" and they will never be re-raised.
Audited: the mnfst/manifest self-hosting/Docker surface (app v6.18.0, clone @126bd7ff8) against the docs at 9eebdf8. Scoped nightly rotation, topic "self-hosting with Docker (install, upgrade, backup)". Window: the full feature surface (
docker/install.sh,docker/docker-compose.yml,docker/.env.example,docker/Dockerfile, the image-signing CI, telemetry) plus the recent self-hosting PRs #2565, #2591, #2693, #1649, #1777, #1785.Page in scope:
self-hosted.mdx(the only page these findings may target).Findings
1 · [OBSOLETE] The "Exposing on the LAN" steps tell you to edit a compose line that no longer exists, and any compose edit is wiped by the next upgrade. The real knob is one line in
.env.Page: https://manifest.build/docs/self-hosted (Exposing on the LAN)
What actually happens:
The behavioral claim is fine: the dashboard does bind to
127.0.0.1by default. Only the "how to change it" instruction is broken.Options:
HOST_BIND_ADDRESS=0.0.0.0in.envand drop the compose edit. Recommended. (IntroducesHOST_BIND_ADDRESSinto the prose, so the page's Core env-var table gains its row and theBIND_ADDRESSnote is re-pointed; suggested wording below. A matching row in the environment-variables reference is needed to keep the two in sync; that is tracked in the backlog, not part of this finding.)--upgradeunless moved to.env..envHOST_BIND_ADDRESSas primary, the compose edit as an advanced override.Suggested wording (option 1)
Replacement for the "Exposing on the LAN"
<Steps>block:New Core env-var table row (insert below the
PORTrow):Re-pointed
BIND_ADDRESSsentence in the<Note>:Evidence (for the agent)
self-hosted.mdx:208—change theportsline from"127.0.0.1:2099:2099"to"2099:2099".; intro Noteself-hosted.mdx:17; theBIND_ADDRESSNoteself-hosted.mdx:326.docker/docker-compose.yml:50— ports line"${HOST_BIND_ADDRESS:-127.0.0.1}:${HOST_PORT:-${PORT:-2099}}:${PORT:-2099}"; the literal127.0.0.1:2099:2099string is absent (grep clean at HEAD). Headerdocker-compose.yml:30-32— "To expose on the LAN, set HOST_BIND_ADDRESS=0.0.0.0 and update BETTER_AUTH_URL in .env".docker/.env.example:28—# HOST_BIND_ADDRESS=0.0.0.0.docker/install.sh:240-251(--upgradedownloads and atomically replacesdocker-compose.yml);.envis never modified by the installer.HOST_BIND_ADDRESS/HOST_PORTports template first shipped in released tagmanifest@6.18.0(absent from 6.17.1 and earlier), same release that added themanifest_request_recordingsvolume (PR #2565).Reply with the finding number and the chosen option
(e.g. "3 → option 2", or "3: other idea, let's discuss").
PRs are then made manually with the agent, never by the harness.
Rejected findings: reply "N → reject" and they will never be re-raised.