Deploying the developer edition on Earth
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.
The host
| Name | earth (earth.andymccall.xyz, IPv6 ULA; 192.168.1.6 on the LAN) |
| OS | Ubuntu 26.04.1 LTS, x86_64, 4 cores, 31 GiB RAM |
| Disk | / 251 GB (95 GB free), /home 1 TB (944 GB free) |
| 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 |
| Not installed | Rust toolchain, sqlite3 CLI, nginx or caddy, certbot |
| Access | ssh -i ~/.ssh/earth_claude claude@earth; claude has passwordless sudo |
Ports 7300 (HTTP) and 7343 (HTTPS) are free and are the hub's.
Steps
- Toolchain (as
claude):curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal, thensudo apt-get install -y build-essential pkg-config git. - 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 pushto the hub itself is the ongoing path. - Build:
cd ~/src/oxygenhub && cargo build --release. - 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). - Service:
/etc/systemd/system/oxygenhub.servicerunningoxygenhub serve --data /home/oxygenhub/dataasoxygenhub,Restart=on-failure,ProtectSystem=strict,ReadWritePaths=/home/oxygenhub/data,NoNewPrivileges=yes;sudo systemctl enable --now oxygenhub. - TLS: the developer edition generates a self-signed certificate at
init. Download the certificate fromhttps://earth.andymccall.xyz:7343/.well-known/oxyhub-ca.pem(or over plain HTTP on port 7300) and point clients at it withoxy config remote.<name>.ca <file>orOXY_CA. - First repositories: on the development machine,
oxy remote add earth https://oxygenhub.io/andymccall/oxygenin each ofoxygen,oxygen-vscode,oxygenhub, thenoxy push earth. - Updates: rsync, build,
sudo install,sudo systemctl restart oxygenhub.make deployin the hub wraps steps 2, 3 and 8. - Public address (2026-09-30): a Cloudflare tunnel on Earth serves the hub as
https://oxygenhub.io, with a publicly trusted certificate, andbase_urlinhub.tomlis that address, so every link the hub writes uses it. Checkouts push there with no CA set. The Flow runner on Earth still reaches the hub on its local address with the self-signed certificate of step 6.
Where things are on Earth
| Binaries | /usr/local/bin/oxygenhub, /usr/local/bin/oxy |
| Sources | /home/claude/src/oxygen, /home/claude/src/oxygenhub (rsync targets; the hub itself is the canonical remote) |
| Data | /home/oxygenhub/data (hub.toml, hub.db, keys/, repos/andymccall/*) |
| Push token | /home/oxygenhub/push-token (also in hub.toml); each local checkout has it as remote.earth.token |
| 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 |
| Service | sudo systemctl status oxygenhub, sudo journalctl -u oxygenhub |