once-add/README.md
28allday 68c64265a6 once-add: deploy + remove Once apps at <name>.local
A small Go tool that wraps the `/etc/hosts` + `once deploy --disable-tls`
recipe needed to host a Once app on a single-label `<name>.local`. Adds
the hosts entry, runs the deploy, polls /up, and on removal cleans the
hosts line that the Once UI orphans (including the orphan-only case,
where the app is already gone).

Bubble Tea TUI for interactive use; non-interactive CLI for scripts.
Curated apps live in /etc/once-add/apps.toml; seeded with Writebook +
Campfire on first run.
2026-05-28 07:23:07 +01:00

73 lines
2.5 KiB
Markdown

# once-add
Deploy and remove a [Once](https://once.com) app at a single-label `<name>.local`
host. Adds the right `/etc/hosts` entry, runs `once deploy --disable-tls`, and
(on removal) cleans the `/etc/hosts` line that the Once UI orphans.
## Why it's needed
Once's binary is statically linked (pure-Go resolver), so its post-deploy
`GET /up` verify resolves `/etc/hosts` + real DNS only — never mDNS — and the
TUI install forces TLS on (no Let's Encrypt cert for a private `.local`). Either
one makes Once roll back the container. `once-add` runs the working recipe:
```sh
echo "127.0.0.1 <name>.local" | sudo tee -a /etc/hosts # so Once's verify resolves it
once deploy <image> --host <name>.local --disable-tls # TLS off; http verify passes
```
For other machines on your LAN to reach the site you'll also need an mDNS
publisher running on the box (something that announces `<name>.local` over
Avahi). Without one, the site is only reachable from the hosting box itself.
## Install
```sh
curl -fsSL https://github.com/28allday/once-add/releases/latest/download/once-add \
-o once-add && sudo install -m 755 once-add /usr/local/bin/once-add && rm once-add
```
## Usage
Runs as root (it edits `/etc/hosts`); self-elevates with `sudo` if needed.
```sh
once-add # interactive wizard (Add / Remove)
once-add book ghcr.io/basecamp/writebook # add (non-interactive)
once-add remove book # remove app + its /etc/hosts entry
once-add remove book --data # also delete the data volume (irreversible)
once-add remove # interactive remove picker
```
**Add** wizard: pick a curated app (or a custom image) → name it → deploy →
reachable at `http://<name>.local`.
**Remove** runs `once remove <host>` and then clears the `/etc/hosts` line
once-add added (the Once UI removes the container but orphans that line). Data
volumes are kept by default — pass `--data` (or tick the toggle in the wizard)
to delete them too. If the app is already gone, the orphaned `/etc/hosts` line
is cleaned up anyway.
## Curated apps
Edit `/etc/once-add/apps.toml` to add entries — no rebuild needed. `once-add`
seeds a default file (Writebook, Campfire) on first run if it's missing.
```toml
[[app]]
name = "Writebook"
image = "ghcr.io/basecamp/writebook"
description = "Books & documentation"
suggested = "book"
```
## Build
```sh
CGO_ENABLED=0 go build -o once-add ./cmd/once-add # static binary
go test ./...
```
## Licence
MIT.