feat: add Database-Gateway Cloudron package (Infrastructure) [#639]
Database Gateway 0.24.0 as the 12th package: multi-stage Go build (CGO required by the libpg_query parser, hence an alpine:3.23 runtime matching upstream), native OIDC wired to the Cloudron platform identity provider, postgresql addon storage with goose migrations applied at start, jq-generated config + OPA policy seeded to /app/data. Verified end-to-end against a throwaway postgres (migrations, policy compile, startup to the OIDC handoff). Docs gardened to 12 packages. Ticket: https://projects.knownelement.com/issues/639
This commit is contained in:
+74
-1
@@ -4,7 +4,7 @@
|
||||
**Project**: TSYSDevStack-SupportStack-Cloudron
|
||||
**Goal**: Package ~57 applications for Cloudron PaaS platform
|
||||
**Start Date**: 2025-01-24
|
||||
**Current Status**: 11/~57 packages completed (~19%)
|
||||
**Current Status**: 12/~57 packages completed (~21%)
|
||||
|
||||
## Completed Packages
|
||||
|
||||
@@ -893,6 +893,79 @@ traversal (frp/ngrok class, Rust); this package runs the **server** side
|
||||
|
||||
**Commit**: `feat: add Rathole Cloudron package (Infrastructure) [#650]`
|
||||
|
||||
### 12. Database Gateway (Infrastructure) ✅
|
||||
**Date**: 2026-09-01
|
||||
**Application**: Database Gateway (dbgw) — policy-checked web gateway to
|
||||
PostgreSQL databases (OIDC login, OPA-authorized queries, cached results)
|
||||
**Package Size**: 93.7MB (alpine runtime; smallest package so far)
|
||||
**Port**: 8080 (httpPort, single listener — web UI + LRPC API)
|
||||
**Addons**: localstorage, postgresql (16)
|
||||
|
||||
**Key Learnings**:
|
||||
- **Auth gate verdict**: NATIVE OIDC, the preferred row — no local users,
|
||||
no LDAP, the only login path is an OIDC provider. Perfect fit for the
|
||||
Cloudron platform provider: `CLOUDRON_OIDC_ISSUER` / `CLIENT_ID` /
|
||||
`CLIENT_SECRET` are written into `users.*` of the seeded config;
|
||||
redirect URL derives from `CLOUDRON_APP_ORIGIN` + `/auth/callback`;
|
||||
roles map from the `groups` claim (Cloudron `admins` → admin,
|
||||
`users` → user). First package in the set to consume the platform
|
||||
OIDC env vars end-to-end
|
||||
- **cgo is load-bearing**: the SQL parser is a libpg_query cgo binding —
|
||||
`CGO_ENABLED=0` fails to compile (`undefined: pg.Parse`). The binary
|
||||
therefore links musl and will not exec on Ubuntu/glibc bases (fails
|
||||
with a misleading "no such file or directory") → runtime base is
|
||||
alpine:3.23, same as upstream's own image, with bash / jq / openssl /
|
||||
postgresql16-client apk-installed for start.sh (the mirror image of the
|
||||
Rathole glibc trap)
|
||||
- **Config is a file, not env**: the app takes one JSON config (`-c`),
|
||||
validated with required `role_mapping` and `policy.path`. start.sh
|
||||
builds it with `jq -n --arg` on first run so secrets are escaped
|
||||
safely into JSON, then admins edit `/app/data/config.json` (targets,
|
||||
role mapping) and `/app/data/opa/simple.rego` (query policy) with the
|
||||
Cloudron file manager; restart applies
|
||||
- **Migrations**: goose SQL embedded in the binary; `migrate-up` subcommand
|
||||
is run explicitly in start.sh (the app also self-migrates on `run` —
|
||||
belt and suspenders, both idempotent)
|
||||
- **Frontend is pre-embedded**: upstream commits `internal/facade/ui/dist`
|
||||
(`go:embed`), so the Go build ships the web UI — no Node stage needed
|
||||
- **Validate() quirks**: targets list may be empty (seed `[]`), but every
|
||||
`tables[].table` must be schema-qualified (`public.foo`) and every
|
||||
role_mapping value must be exactly `admin` or `user`
|
||||
|
||||
**Build Process**:
|
||||
- Upstream `kazhuravlev/database-gateway` v0.24.0 (GPL-3.0, Go 1.26.1)
|
||||
built from the cloned repo (multi-stage pattern #2): golang:1.26-alpine
|
||||
builder mirrors the upstream Dockerfile (CGO_ENABLED=1 + ldflags
|
||||
version stamp) → alpine:3.23 runtime
|
||||
- Logo: upstream `frontend/src/favicon-96x96.png` copied directly
|
||||
- start.sh: psql wait loop on the postgresql addon → seed `.cookie_secret`
|
||||
(openssl rand -hex 32), `opa/simple.rego` (admins-only default),
|
||||
`config.json` (jq template) → `migrate-up` → `exec run`
|
||||
|
||||
**Validation**:
|
||||
- `docker build --cgroup-parent ukrrs-batch.slice -t
|
||||
database-gateway-cloudron:test` → green
|
||||
- `--version` smoke in the image → `gateway version v0.24.0`
|
||||
- End-to-end vs a throwaway postgres:16-alpine on a docker network with
|
||||
fake CLOUDRON_* env: PG wait loop, config + policy seeding, all 5
|
||||
goose migrations applied (bookmarks / query_results tables verified
|
||||
with psql), rego policy compiled, gateway reached the OIDC discovery
|
||||
step and failed only on the bogus issuer (expected off-Cloudron; the
|
||||
real platform issuer resolves at install time)
|
||||
|
||||
**Files Created**:
|
||||
- Dockerfile (multi-stage Go, CGO, alpine:3.23 runtime)
|
||||
- CloudronManifest.json (manifestVersion 2, httpPort 8080, localstorage +
|
||||
postgresql 16)
|
||||
- start.sh (DB wait, jq config seed, policy seed, migrate-up, exec) —
|
||||
committed executable
|
||||
- README.md (auth story, config guide, target walkthrough)
|
||||
- CHANGELOG.md
|
||||
- .env.example (Cloudron-provided env documented)
|
||||
- logo.png (96x96, upstream favicon)
|
||||
|
||||
**Commit**: `feat: add Database-Gateway Cloudron package (Infrastructure) [#639]`
|
||||
|
||||
---
|
||||
|
||||
## Packaging Pattern: Download Pre-Compiled Binaries
|
||||
|
||||
Reference in New Issue
Block a user