One-command install
The recommended install path is a single script downloaded from the GitHub
release, verified with cosign, and handed off to a deploy script that lives
inside the signed tarball. Two scripts, one trust boundary.
Prerequisites
Section titled “Prerequisites”| What | Why |
|---|---|
| Fresh Ubuntu 22.04 / 24.04 VPS | Tested OS. Debian stable likely works; other distros at your own risk. |
| Public IPv4 (and ideally IPv6) | Caddy needs to reach Let’s Encrypt for ACME. |
| DNS A/AAAA record pointing at the VPS | The hostname is locked into the systemd env on first run. |
| Ports 80 + 443 open inbound | 80 for ACME, 443 for the SPA. |
| Root or sudo | The script writes to /opt, /etc, and the systemd unit dir. |
install.sh does not open ports, edit SSH config, change the firewall, or
install anything other than Caddy and the relay. Those decisions are yours;
the optional sudo wattcloud harden covers them.
What the install does, step by step
Section titled “What the install does, step by step”curl -sSLO https://github.com/wattzupbyte/wattcloud/releases/latest/download/install.shless install.sh # ~150 lines — read before runningsudo bash install.sh cloud.example.comUnder the hood:
- Resolve the latest stable release via the GitHub API. Prerelease tags
(
-rc,-beta) are skipped so you can’t accidentally land on one. - Download the per-arch tarball, signature, and certificate to a temp dir.
- Verify with
cosign verify-blobagainstTRUSTED_SIGNER_IDENTITY— the project’s pinned Sigstore identity regex. Forks override this in/etc/wattcloud/wattcloud.env; no script patching required. - Extract to
/opt/wattcloud/releases/vX.Y.Z/and atomically symlink/opt/wattcloud/current→ that directory. - Hand off to
deploy-vps.shfrom inside the verified tarball. The outerinstall.shis now done.
deploy-vps.sh then:
- Installs Caddy from its official APT repo if it is not already present.
- Renders
packaging/Caddyfile.tmplinto/etc/caddy/Caddyfilewith the hostname and a fresh ACME email, and reloads Caddy. - Generates 32-byte JWT and HMAC signing keys into
/etc/wattcloud/wattcloud.envif it does not exist. Existing env files are not overwritten — re-running the install on an already-claimed host is safe. - Renders
packaging/config.json.tmplinto/var/lib/wattcloud/config.jsonfor the SPA’s runtime config (Cache-Control: no-store). - Installs
packaging/wattcloud.service(sandboxed systemd unit:DynamicUser=yes,ProtectSystem=strict,MemoryDenyWriteExecute=yes, capabilities dropped, seccomp filter on) into/etc/systemd/system/. daemon-reload, enable, start.- Polls
https://cloud.example.com/healthfor up to 30 s. If the service does not come back green, the install aborts and the unit is rolled back.
After install — what landed on disk
Section titled “After install — what landed on disk”Directory/opt/wattcloud/
- current → releases/vX.Y.Z/ [symlink]
Directoryreleases/
DirectoryvX.Y.Z/
Directorybin/
- byo-relay
Directoryweb/
- (built SPA assets)
Directoryscripts/
- deploy-vps.sh
- update.sh
- harden-vps.sh
- …
Directorypackaging/
- …
Directory/etc/wattcloud/
- wattcloud.env [0600 — generated signing keys + config]
Directory/var/lib/wattcloud/
- config.json [SPA runtime config]
Directorystate/ [enrollment journal, share blobs, claim tokens]
- …
- /etc/systemd/system/wattcloud.service
- /etc/caddy/Caddyfile
/var/lib/wattcloud/state/ is the only directory the relay writes to at
runtime. It holds enrollment cookies, ephemeral share blobs (sweeper-purged
on expiry), and one-time claim tokens. No client IPs, no plaintext, no
filenames.
Non-interactive install
Section titled “Non-interactive install”For Ansible / cloud-init / scripted setup:
sudo bash install.sh cloud.example.com --yes--yes accepts the cosign-verified-then-extract step without a prompt.
Everything else is already non-interactive.
Forks: replacing the trusted signer
Section titled “Forks: replacing the trusted signer”The default identity regex is hard-coded for the upstream project. If you publish your own signed releases:
echo 'TRUSTED_SIGNER_IDENTITY=^https://github\.com/your-fork/wattcloud/' \ | sudo tee -a /etc/wattcloud/wattcloud.envinstall.sh and wattcloud-update honour the env override before doing
anything else. There is no “skip verification” flag and there will not be
one — if cosign verify-blob fails, the install aborts.
Adjacent docs
Section titled “Adjacent docs”- The full recipe to claim ownership and lock the instance down → Access control.
- The matching update path with auto-rollback → Upgrade & rollback.
- Opt-in VPS hardening (UFW, fail2ban, sshd, R5 logging) → VPS hardening.
- When something goes wrong during install → Troubleshooting.