OXYGENHUB
◆ clear-waiting oxygenhub / docs / deploy.md
4.1 KiB · Markdown · last changed Earth serves the hub on localhost only, behind the tunnel 1 month ago renderedsource blame history raw
1
# Deploying the developer edition on Earth
2
3
Companion to `spec.md` §17.5. Status: **installed and running** since 2026-09-27 as the systemd service `oxygenhub` under the `oxygenhub` system user, data in `/home/oxygenhub/data`, HTTP on 7300 and HTTPS on 7343 with a self-signed certificate. `oxygen`, `oxygen-vscode` and `oxygenhub` are hosted under `andymccall/` and each checkout has an `earth` remote.
4
5
## The host
6
7
| | |
8
|---|---|
9
| Name | `earth` (`earth.andymccall.xyz`, IPv6 ULA; `192.168.1.6` on the LAN) |
10
| OS | Ubuntu 26.04.1 LTS, x86_64, 4 cores, 31 GiB RAM |
11
| Disk | `/` 251 GB (95 GB free), `/home` 1 TB (944 GB free) |
12
| Already running | sshd :22, a Python service :6400, `wren-nest` :7842, retroplay-manager in Docker (:8080, :6670) with Postgres and a tetriblox server, two GitHub Actions runners (`doomsdayonecom`), Docker, containerd |
13
| Not installed | Rust toolchain, sqlite3 CLI, nginx or caddy, certbot |
14
| Access | `ssh -i ~/.ssh/earth_claude claude@earth`; `claude` has passwordless sudo |
15
16
Ports 7300 (HTTP) and 7343 (HTTPS) are free and are the hub's.
17
18
## Steps
19
20
1. **Toolchain** (as `claude`): `curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal`, then `sudo apt-get install -y build-essential pkg-config git`.
21
2. **Source**: from the development machine, `rsync -a --delete --exclude target --exclude node_modules ~/development/oxygen ~/development/oxygenhub claude@earth:~/src/`. Oxygen is never pushed to Git; rsync is the bootstrap, and after the hub runs, `oxy push` to the hub itself is the ongoing path.
22
3. **Build**: `cd ~/src/oxygenhub && cargo build --release`.
23
4. **System user and data**: `sudo useradd --system --home /home/oxygenhub --create-home oxygenhub`, `sudo install -o oxygenhub -g oxygenhub -m 0755 target/release/oxygenhub /usr/local/bin/`, `sudo -u oxygenhub oxygenhub init --data /home/oxygenhub/data --admin andymccall` (prints the first admin's one-time password).
24
5. **Service**: `/etc/systemd/system/oxygenhub.service` running `oxygenhub serve --data /home/oxygenhub/data` as `oxygenhub`, `Restart=on-failure`, `ProtectSystem=strict`, `ReadWritePaths=/home/oxygenhub/data`, `NoNewPrivileges=yes`; `sudo systemctl enable --now oxygenhub`.
25
6. **TLS**: the developer edition generates a self-signed certificate at `init`. Download the certificate from `https://earth.andymccall.xyz:7343/.well-known/oxyhub-ca.pem` (or over plain HTTP on port 7300) and point clients at it with `oxy config remote.<name>.ca <file>` or `OXY_CA`.
26
7. **First repositories**: on the development machine, `oxy remote add earth https://oxygenhub.io/andymccall/oxygen` in each of `oxygen`, `oxygen-vscode`, `oxygenhub`, then `oxy push earth`.
27
8. **Updates**: rsync, build, `sudo install`, `sudo systemctl restart oxygenhub`. `make deploy` in the hub wraps steps 2, 3 and 8.
28
9. **Public address** (2026-09-30): a Cloudflare tunnel on Earth serves the hub as `https://oxygenhub.io`, with a publicly trusted certificate, and `base_url` in `hub.toml` is that address, so every link the hub writes uses it. Checkouts push there with no CA set, and subrepo URLs name it too.
29
10. **Localhost only** (2026-09-30): the tunnel connects to `127.0.0.1:7300`, so the hub binds `127.0.0.1:7300` and `127.0.0.1:7343` and nothing on the LAN reaches it directly; `behind_proxy = true` (the hub does not yet use client addresses). The Flow runner on Earth polls `http://127.0.0.1:7300`. Backups: `hub.toml.before-localhost`, `~/flow/flow.toml.before-localhost`.
30
31
## Where things are on Earth
32
33
| | |
34
|---|---|
35
| Binaries | `/usr/local/bin/oxygenhub`, `/usr/local/bin/oxy` |
36
| Sources | `/home/claude/src/oxygen`, `/home/claude/src/oxygenhub` (rsync targets; the hub itself is the canonical remote) |
37
| Data | `/home/oxygenhub/data` (`hub.toml`, `hub.db`, `keys/`, `repos/andymccall/*`) |
38
| Push token | `/home/oxygenhub/push-token` (also in `hub.toml`); each local checkout has it as `remote.earth.token` |
39
| Certificate | `/home/oxygenhub/data/keys/tls.crt`, served at `/.well-known/oxyhub-ca.pem`; local copy `~/.config/oxy/earth-ca.pem` set as `remote.earth.ca` |
40
| Service | `sudo systemctl status oxygenhub`, `sudo journalctl -u oxygenhub` |