feat: add Rathole Cloudron package (Infrastructure) [#650]

Server-mode Rathole 0.5.0 as the 11th package: pinned upstream binary
(sha256 gate) on cloudron/base:4.0.0, control port 2333 plus a 100-port
tunnel exit range, hot-reloading config in /app/data, auth-proxy verdict
(no user concept). Verified end-to-end with a live client tunnel.
Docs gardened (STATUS/README/JOURNAL to 11 packages).

Ticket: https://projects.knownelement.com/issues/650
This commit is contained in:
2026-09-01 19:02:51 -05:00
parent 8d0b0f42f6
commit f918a90c3b
12 changed files with 415 additions and 13 deletions
+73 -1
View File
@@ -4,7 +4,7 @@
**Project**: TSYSDevStack-SupportStack-Cloudron
**Goal**: Package ~57 applications for Cloudron PaaS platform
**Start Date**: 2025-01-24
**Current Status**: 10/~57 packages completed (~18%)
**Current Status**: 11/~57 packages completed (~19%)
## Completed Packages
@@ -823,6 +823,78 @@ Dockerfile
---
### 11. Rathole (Infrastructure) ✅
**Date**: 2026-09-01
**Application**: Rathole — secure, high-performance reverse proxy for NAT
traversal (frp/ngrok class, Rust); this package runs the **server** side
**Package Size**: 3.51GB (cloudron/base 4.0.0 dominates)
**Ports**: 8000 (HTTP status), 2333 (control), 5200-5299 (tunnel exits)
**Addons**: localstorage (auth proxy, no database)
**Key Learnings**:
- **Auth gate verdict**: NO user concept — no UI, no accounts, no SSO
hooks. Tunnels are authorized by mandatory per-service tokens
(random `default_token` seeded on first run), with optional Noise/TLS
transport encryption → `httpAuth.type = proxy` gates the only HTTP
surface (a static status page), the draw.io/Easy-Gate pattern for
user-less apps
- **Base-image glibc trap**: upstream dropped musl release builds in
v0.5.0 (TLS linking burden); the only linux/amd64 asset is
`x86_64-unknown-linux-gnu`, built on ubuntu-latest → needs glibc
>= 2.35 → `cloudron/base:4.0.0` (22.04). The 3.2.0 (20.04) base used
by earlier packages is too old for this binary
- **Strict TOML schema quirks**: v0.5.0 rejects `nodelay` directly under
`[server.transport]` (must nest under `[server.transport.tcp]`) and
rejects a server config with **zero** `[server.services.*]` blocks —
the seed config must ship one active placeholder service
- **Lazy service binding**: the server binds a service's exit port only
when its client registers — an empty listener table is normal until a
client connects
- **tcpPorts ranges**: CloudronManifest `portCount` allocates sequential
ports from `defaultValue` (max 1000) with `containerPort` bridging —
used for a 100-port tunnel exit range (5200-5299) that survives
admin-chosen external renumbering without touching server.toml
- **httpPort is required** (healthCheckPath too) even for headless TCP
apps: a tiny `python3 -m http.server` sidecar on the status page
satisfies both and gives the auth proxy something to gate
**Build Process**:
- Upstream `rathole-org/rathole` v0.5.0 (rapiz1 redirects) release zip
downloaded in-Dockerfile behind a sha256 pin (pre-compiled-binaries
pattern, JOURNAL pattern #5)
- Logo: upstream wordmark (1080x291) resized/padded to 256x256 PNG via
ImageMagick in a throwaway `alpine:3.20` container (host stays clean)
- start.sh: seeds `/app/data/server.toml` (random default_token via
openssl + placeholder `[server.services.example]` on :5200), starts
the status-page sidecar, `exec rathole --server` (config hot-reloads
on save)
**Validation**:
- `docker build --cgroup-parent ukrrs-batch.slice -t rathole-cloudron:test`
→ green (sha256 gate + `rathole --version` inside the build)
- Runtime smoke: status page HTTP 200, control port :2333 reachable,
hot-reload detected an appended service within 3s
- **End-to-end tunnel test**: second container ran `rathole --client`
against the packaged server; `curl host:15200 → server:5200 →
client → client:9999` returned the client's page — token auth,
control channel, data plane, and lazy bind all proven
**Files Created**:
- Dockerfile (pre-compiled binary, sha256-pinned, cloudron/base:4.0.0)
- CloudronManifest.json (manifestVersion 2, httpAuth proxy, tcpPorts:
CONTROL_PORT 2333 + SERVICE_PORT 5200 x100, localstorage)
- start.sh (config seed + status sidecar + exec) — committed executable
- status.html (auth-proxied landing/health page)
- README.md (auth story, ports, client quickstart)
- CHANGELOG.md
- .env.example (RUST_LOG knob)
- .dockerignore (excludes the whole cloned repo/ from context)
- logo.png (256x256)
**Commit**: `feat: add Rathole Cloudron package (Infrastructure) [#650]`
---
## Packaging Pattern: Download Pre-Compiled Binaries
### When to Use