Skip to content

fix(pods): bind-mount host public_html into the pod so ~/public_html is served#25

Merged
ralyodio merged 1 commit into
mainfrom
fix/pod-public-html-bind-mount
Jun 15, 2026
Merged

fix(pods): bind-mount host public_html into the pod so ~/public_html is served#25
ralyodio merged 1 commit into
mainfrom
fix/pod-public-html-bind-mount

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Problem

A member's pod home (/home/dev) is a named container volume, but Caddy serves <name>.<host> from the host path <data>/users/<name>/public_html. The two were disconnected, so editing ~/public_html/index.html in the pod never changed the served page — contradicting the on-screen "edit ~/public_html to make it yours" instruction.

Fix

Bind-mount <data>/users/<user>/public_html at /home/dev/public_html when pods start, so a member's ~/public_html is the directory Caddy serves.

  • Detect(usersDir string) now takes the host users dir; pass "" to disable the bind.
  • New publicHTMLMount() resolves + creates the host dir and returns the -v spec.
  • Docker fallback (uid 1000): the one-shot init container also chowns the bind path. Rootless podman maps container root to the host service user that already owns the tree, so no chown needed there.
  • Adds the first unit tests for internal/pods.

Deployment notes

  • Existing pods must be recreated to pick up the mount (ensure() only adds mounts on container create): podman rm -f agentbbs-pod-<name> — recreated on next ssh pod@.
  • After recreation the bind overlays the named volume's old public_html, so any content previously written there is shadowed by the host dir.

🤖 Generated with Claude Code

…is served

A member's pod home (/home/dev) is a named container volume, but Caddy serves
<name>.<host> from the host path <data>/users/<name>/public_html. The two were
disconnected, so editing ~/public_html/index.html in the pod never changed the
served page — contradicting the on-screen "edit ~/public_html to make it yours"
instruction.

Bind-mount <data>/users/<user>/public_html at /home/dev/public_html when pods
start. The host tree is created if absent so the mount source exists, and under
the docker fallback (uid 1000) the one-shot init container now also chowns the
bind path; rootless podman maps container root to the host service user that
already owns the tree, so no chown is needed there.

Detect now takes the host users dir; pass "" to disable the bind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ralyodio ralyodio merged commit cbe7a44 into main Jun 15, 2026
@github-actions

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

ralyodio added a commit that referenced this pull request Jun 15, 2026
…n box (#27)

The deploy SSHed into the ~458MB droplet and ran `go build` there. The Go
linker's peak memory OOM-killed the build — and with it the sshd serving the
deploy session — surfacing as "Connection closed by remote host" (exit 255).
It was flaky because it tracked momentary memory pressure from the co-resident
ergo/forgejo/tor/podman/agentbbs processes (run #25 passed, #26 failed on
near-identical code).

Build both binaries on the 16GB GitHub runner instead (pure-Go, modernc
sqlite, so CGO_ENABLED=0 static cross-build), scp them to the droplet, and run
setup.sh with SKIP_BUILD=1 so the box never compiles. Arch is detected from
the droplet so amd64/arm64 both work. setup.sh now also skips the Go toolchain
download when SKIP_BUILD=1.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
ralyodio added a commit that referenced this pull request Jun 15, 2026
* fix(deploy): build Go binaries on the runner, ship them, SKIP_BUILD on box

The deploy SSHed into the ~458MB droplet and ran `go build` there. The Go
linker's peak memory OOM-killed the build — and with it the sshd serving the
deploy session — surfacing as "Connection closed by remote host" (exit 255).
It was flaky because it tracked momentary memory pressure from the co-resident
ergo/forgejo/tor/podman/agentbbs processes (run #25 passed, #26 failed on
near-identical code).

Build both binaries on the 16GB GitHub runner instead (pure-Go, modernc
sqlite, so CGO_ENABLED=0 static cross-build), scp them to the droplet, and run
setup.sh with SKIP_BUILD=1 so the box never compiles. Arch is detected from
the droplet so amd64/arm64 both work. setup.sh now also skips the Go toolchain
download when SKIP_BUILD=1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(members): member directory + store-and-forward messaging

A members-only hub plugin (the BBS "who") plus user-to-user messaging:

- internal/store: messages table + SendMessage/Inbox/UnreadCount/MarkRead, and
  OnlineUsers (open sessions) for presence. MarkRead is recipient-scoped so a
  member can only clear their own mail.
- plugins/members: directory with online dots + last-seen, a finger-style
  profile view, a minimal compose box, and an inbox that marks read on open.
- ssh msg@host <user> [text]: scriptable CLI to leave a note (body from args or
  stdin), mirroring the existing finger route; "msg"/"message" are reserved.
- hub: "N unread" badge on login (hubMOTD). plugin.Context gains Host for member
  homepage URLs.

Extends the existing finger@ behavior (ssh <name>@host) rather than replacing it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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