feat: add FX Cloudron package (DevOps-Tools) [#640]

FX 0.9.48 ("poor man's function as a service") as the 13th package:
pre-compiled goreleaser release binary with sha256 pin on
cloudron/base:4.0.0. fx is a CLI with no user concept, so the package
is a workstation: pinned binary + persistent workspace
(functions/ssh/kube) driven from the Cloudron web terminal, with an
auth-proxied landing page as the only HTTP surface (httpAuth proxy).
Deploys target remote Docker hosts over key-based SSH or Kubernetes
via FX_KUBECONF. Build green; runtime smoke (landing page, workspace
seeding, fx -v) green. Docs gardened to 13 packages.

Ticket: https://projects.knownelement.com/issues/640
This commit is contained in:
2026-09-01 19:39:53 -05:00
parent 3d38c507e8
commit 10e2b7c7ed
12 changed files with 412 additions and 13 deletions
+71 -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**: 12/~57 packages completed (~21%)
**Current Status**: 13/~57 packages completed (~23%)
## Completed Packages
@@ -966,6 +966,76 @@ PostgreSQL databases (OIDC login, OPA-authorized queries, cached results)
**Commit**: `feat: add Database-Gateway Cloudron package (Infrastructure) [#639]`
### 13. FX (DevOps-Tools) ✅
**Date**: 2026-09-01
**Application**: FX — "poor man's function as a service" (metrue/fx): a CLI
that turns a stateless function file (JS, Python, Go, Ruby, Java, PHP,
Perl, Crystal, Rust, Julia, D) into a running HTTP service on your own
Docker host or Kubernetes cluster
**Package Size**: 3.55GB (cloudron/base 4.0.0 dominates)
**Ports**: 8000 (HTTP landing/health page only — fx itself listens on
nothing)
**Addons**: localstorage (auth proxy, no database)
**Key Learnings**:
- **Auth gate verdict**: NO user concept — fx is a terminal tool: no UI,
no accounts, no SSO hooks → `httpAuth.type = proxy` gates the only
HTTP surface (the landing page), the Rathole/Easy-Gate pattern for
user-less apps. Terminal + workspace access is Cloudron's app access
list; the SSH keys under /app/data/ssh are target credentials
- **First pure "CLI workstation" package**: fx has no daemon, so the
landing-page server (python3 -m http.server) is the ONLY long-running
process; the fx binary runs on demand from the Cloudron web terminal.
Package value = pinned binary + persistent workspace
(/app/data/{functions,ssh,kube})
- **No Docker daemon in Cloudron apps** (and no host socket access):
fx's local-docker mode is unusable in-app; deploys target remote
Docker hosts over SSH (Go-native ssh library, key-based — no
openssh binary needed in the image) or Kubernetes via FX_KUBECONF
- **Release pinning on a quiet upstream**: last published release is
0.9.48-alpha.d91a7a0 (2021-06-10) while master sits at 2023-10-24;
packaged the release (what official scripts/install.sh installs; the
binary self-reports 0.9.48), not master
- **glibc trap, Rathole side**: the goreleaser `Tux` asset is
glibc-built → Ubuntu base (cloudron/base:4.0.0); the mirror image of
Database Gateway's musl/alpine pairing
- **Starter functions must match upstream shapes exactly**: JS =
Koa-style `(ctx) => { ctx.body = ... }`, Python = plain
`def fx(request)` — copied from upstream examples verbatim
**Build Process**:
- Pre-compiled-binaries pattern (JOURNAL pattern #5): release tarball
`fx_0.9.48-alpha.d91a7a0_Tux_64-bit.tar.gz` downloaded in-Dockerfile
behind a sha256 pin taken from the upstream checksums.txt; `fx -v`
runs inside the build as an executability gate
- Logo: 256x256 "fx" monogram generated in a throwaway alpine:3.20
container (upstream ships no logo asset)
- start.sh: seeds the /app/data workspace (functions/ssh/kube + two
starter functions) then execs the landing-page server in the
foreground — committed executable
**Validation**:
- `docker build --cgroup-parent ukrrs-batch.slice -t fx-cloudron:test`
→ green (sha256 gate OK, `fx version 0.9.48` printed in-build)
- Runtime smoke: container up, `GET /` → 200 with the FX landing page,
workspace dirs + hello.js/hello.py seeded, startup banner in logs;
container removed after test
**Files Created**:
- Dockerfile (pre-compiled binary, sha256-pinned, cloudron/base:4.0.0)
- CloudronManifest.json (manifestVersion 2, httpAuth proxy, httpPort
8000, localstorage only)
- start.sh (workspace seed + landing-page server, exec) — committed
executable
- status.html (auth-proxied landing/usage page)
- README.md (auth story, terminal workflow, remote/K8s usage)
- CHANGELOG.md
- .env.example (FX_HOST / FX_KUBECONF knobs)
- .dockerignore (excludes the cloned repo/ from the build context)
- logo.png (256x256 monogram)
**Commit**: `feat: add FX Cloudron package (DevOps-Tools) [#640]`
---
## Packaging Pattern: Download Pre-Compiled Binaries