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.
73 lines
2.5 KiB
Markdown
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.
|