feat: add Easy-Gate Cloudron package (Infrastructure) [#651]

Easy Gate 2.0.3 dashboard hub: multi-stage Go build (static binary on
cloudron/base 3.2.0), config persisted at /app/data/easy-gate.json with
real-time hot reload. No user model (IP-subnet groups only), so the app
ships behind the Cloudron auth proxy (httpAuth.type=proxy); localstorage
addon only, no database. Build validated green + smoke test HTTP 200.
Docs synced (STATUS/README/JOURNAL at 10/~57).

Ticket: https://projects.knownelement.com/issues/651

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
2026-09-01 18:34:29 -05:00
parent c17788d6bf
commit 8d0b0f42f6
10 changed files with 275 additions and 13 deletions
+52 -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**: 7/~57 packages completed (~12%)
**Current Status**: 10/~57 packages completed (~18%)
## Completed Packages
@@ -770,6 +770,57 @@ Dockerfile
**Commit**: `feat: add Windmill Cloudron package (Automation)`
### 10. Easy-Gate (Infrastructure) ✅
**Date**: 2026-09-01
**Application**: Easy Gate — web dashboard hub for self-hosted infrastructure
(config-file driven, real-time hot reload, IP-subnet group visibility)
**Package Size**: 3.18GB (cloudron/base 3.2.0 dominates)
**Port**: 8080
**Addons**: localstorage (auth proxy, no database)
**Key Learnings**:
- **Auth gate verdict**: Easy Gate has NO user model at all — visibility is
purely IP-subnet based (groups with CIDR ranges), no login/OIDC/LDAP
anywhere in the codebase → packaged with `httpAuth.type = proxy` (the
draw.io pattern for user-less apps)
- Multi-stage Go build from the cloned repo (Webhook pattern):
`golang:1.23-alpine` builder, `CGO_ENABLED=0 -trimpath -ldflags="-w -s"`
(mirrors upstream Makefile), static binary onto `cloudron/base:3.2.0`
- Config-driven design: the app re-parses `easy-gate.json` every second —
no restart needed on config edits; start.sh only seeds the first copy
- `behind_proxy: true` matters on Cloudron: group subnet matching uses
`X-Forwarded-For` (Cloudron's nginx passes the real client IP)
- No `.env.example` shipped: the only knob is the JSON config file itself
(documented in the package README instead)
- Package-root `.dockerignore` (`repo/.git`, `repo/.github`, ...) keeps the
cloned repo's git history out of the build context (webhook shipped
without one and paid the context-size cost)
**Build Process**:
- Upstream `wiredlush/easy-gate` v2.0.3 cloned into `repo/` (gitignored)
- `go mod download` cached before `COPY repo/ .` for layer reuse
- Logo converted from upstream `assets/logo.svg` to a 234x256 PNG via
ImageMagick on the host
- start.sh: seeds `/app/data/easy-gate.json` on first run, then
`exec /usr/local/bin/easy-gate` (env `EASY_GATE_CONFIG_PATH`)
**Validation**:
- `docker build --cgroup-parent ukrrs-batch.slice -t easy-gate-cloudron:test` → green
- Throwaway smoke container: `GET /` → HTTP 200, seeded config verified
(`behind_proxy: true`), container removed after test
**Files Created**:
- Dockerfile (multi-stage Go build)
- CloudronManifest.json (port 8080, localstorage only, httpAuth proxy,
healthCheckPath /, 256MB memory)
- start.sh (first-run config seed) — committed executable
- README.md (auth story, config table, usage)
- CHANGELOG.md
- .dockerignore (build-context hygiene)
- logo.png (upstream logo.svg → PNG)
**Commit**: `feat: add Easy-Gate Cloudron package (Infrastructure) [#651]`
---
## Packaging Pattern: Download Pre-Compiled Binaries
@@ -0,0 +1,4 @@
repo/.git
repo/.github
repo/build
repo/dist
@@ -0,0 +1,15 @@
# Changelog — Easy Gate Cloudron Package
## 1.0.0 (2026-09-01)
Initial Cloudron package for Easy Gate 2.0.3.
- Multi-stage build: Go 1.23 builder (`CGO_ENABLED=0`, upstream Makefile
flags) producing a static binary on `cloudron/base:3.2.0`.
- `start.sh` seeds `/app/data/easy-gate.json` on first run with
`behind_proxy: true` (Cloudron nginx passes the real client IP via
`X-Forwarded-For` for group subnet matching), then execs the binary.
- `httpAuth.type = proxy`: Easy Gate has no user model, so Cloudron's
authentication proxy gates access.
- Addons: `localstorage` only (config persistence; no database).
- Logo converted from upstream `assets/logo.svg` to a 256px PNG.
@@ -0,0 +1,25 @@
{
"version": 1,
"manifestVersion": 2,
"type": "app",
"id": "io.cloudron.easygate",
"title": "Easy Gate",
"description": "Easy Gate is a web application that serves as the central hub for your self-hosted infrastructure. Services and notes are parsed in real time from a JSON/YAML config file (hot reload, no restarts), and items can be assigned to user groups that only see them based on their IP subnet. No database required.",
"author": "wiredlush",
"website": "https://github.com/wiredlush/easy-gate",
"contactEmail": "cloudron@tsys.dev",
"tagline": "A gate to your self-hosted infrastructure",
"version": "2.0.3",
"healthCheckPath": "/",
"httpPort": 8080,
"httpAuth": {
"type": "proxy"
},
"memoryLimit": 256,
"addons": {
"localstorage": true
},
"mediaLinks": [],
"changelog": "Initial Cloudron package for Easy Gate 2.0.3. Config-driven dashboard hub with no user model, fronted by the Cloudron authentication proxy; configuration persists at /app/data/easy-gate.json with real-time hot reload.",
"icon": "file://logo.png"
}
@@ -0,0 +1,38 @@
# Easy Gate Cloudron Package
#
# Easy Gate is a web dashboard that acts as the central hub for self-hosted
# infrastructure: services and notes are parsed in real time (hot reload,
# once per second) from a JSON/YAML config file, and items can be assigned
# to user groups which only see them based on their IP subnet.
#
# Upstream: https://github.com/wiredlush/easy-gate (v2.0.3, Go 1.23, Fiber)
# - Single static binary (CGO_ENABLED=0), listens on 0.0.0.0:8080
# - No database, no user accounts, no migrations
#
# Authentication: Easy Gate has NO user concept (IP-subnet grouping only).
# Packaged behind Cloudron's authentication proxy (httpAuth.type = proxy).
FROM golang:1.23-alpine AS builder
WORKDIR /easy-gate
# Cache dependency downloads separately from source changes.
COPY repo/go.mod repo/go.sum ./
RUN go mod download
# Build the static binary (mirrors upstream Makefile flags).
COPY repo/ .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-w -s" -o build/easy-gate cmd/easy-gate/main.go
FROM cloudron/base:3.2.0
COPY --from=builder /easy-gate/build/easy-gate /usr/local/bin/easy-gate
# start.sh seeds /app/data/easy-gate.json on first run (behind_proxy: true)
# and execs the binary. Made executable on the host, not at build time.
COPY start.sh /app/start.sh
WORKDIR /app/data
EXPOSE 8080
CMD ["/bin/bash", "/app/start.sh"]
@@ -0,0 +1,75 @@
# Easy Gate Cloudron Package
## Description
Easy Gate is a simple web application that serves as the central hub for
your self-hosted infrastructure. Services and notes are parsed in real time
from a JSON/YAML configuration file — Easy Gate re-reads it every second, so
changes apply immediately without restarts. Services and notes can be
organized into categories and assigned to user groups, so items are shown
only to users matching specific IP subnets (e.g. LAN vs VPN).
This package builds the upstream Go source (v2.0.3) as a static binary and
runs it on the Cloudron base image.
## Authentication
Easy Gate has **no built-in user model** — visibility is controlled by
IP-subnet groups, not accounts. This package therefore uses **Cloudron's
authentication proxy** (`httpAuth.type = proxy` in `CloudronManifest.json`).
The Cloudron admin restricts which platform users/groups may reach the app;
authorized users must present Cloudron credentials before the dashboard
loads. This is the recommended pattern for utility apps without their own
user directory.
Because Cloudron fronts the app with its reverse proxy, the seeded config
sets `behind_proxy: true` so group matching uses the real client IP from
`X-Forwarded-For`.
## Features
- Real-time config parsing (JSON or YAML) with no application restarts
- Group-based visibility of services and notes by client IP subnet
- Service categories, themes, and custom CSS support
- Standalone static Go binary with no external dependencies
- No database required
## Configuration
### Ports
- **8080**: Easy Gate HTTP (the only exposed port)
### Config file
All configuration lives in **`/app/data/easy-gate.json`** (created with a
sane default on first start). Edit it with the Cloudron file manager;
changes are picked up within a second. Key options:
| Option | Purpose |
|--------|---------|
| `title` | Dashboard title |
| `theme.background` / `theme.foreground` | Colors; or `theme.custom_css` for a custom stylesheet |
| `groups[].name` / `groups[].subnet` | Groups defined by client IP subnet (CIDR) |
| `services[]` | Entries: `name`, `url`, `category`, `groups`, `icon` |
| `notes[]` | Entries: `name`, `text`, `groups` |
| `behind_proxy` | Keep `true` on Cloudron (real client IP via X-Forwarded-For) |
Items with an empty `groups` list are visible to everyone (whoever passes
the Cloudron auth proxy).
### Storage
- **`/app/data`** (localstorage addon) holds the config file. Nothing else
is persisted; no database addon is used.
## Usage
1. Install the package on Cloudron.
2. In the Cloudron access control, grant the desired users/groups access.
3. Open the app location — you'll be prompted for Cloudron credentials.
4. Edit `/app/data/easy-gate.json` to list your services and notes; the
dashboard updates within a second.
## Upstream
- **Repository**: https://github.com/wiredlush/easy-gate
- **Version packaged**: 2.0.3 (Go 1.23, Fiber)
- **License**: MIT
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash
set -euo pipefail
# Easy Gate is entirely config-file driven. The config lives in /app/data so
# it survives restarts and updates; seed a Cloudron-friendly default on first
# run. "behind_proxy" is true because Cloudron fronts the app with its nginx:
# X-Forwarded-For carries the real client IP, which the group subnet matching
# relies on.
export EASY_GATE_CONFIG_PATH="/app/data/easy-gate.json"
if [[ ! -f "${EASY_GATE_CONFIG_PATH}" ]]; then
cat > "${EASY_GATE_CONFIG_PATH}" <<'EOF'
{
"addr": "0.0.0.0:8080",
"use_tls": false,
"cert_file": "",
"key_file": "",
"behind_proxy": true,
"title": "Easy Gate",
"theme": {
"background": "#FFFFFF",
"foreground": "#000000"
},
"groups": [
{
"name": "lan",
"subnet": "192.168.0.0/16"
}
],
"services": [
{
"name": "Cloudron",
"category": "Platform",
"url": "https://my.example.com",
"groups": []
}
],
"notes": [
{
"name": "How to configure",
"text": "Edit /app/data/easy-gate.json with the Cloudron file manager. Easy Gate re-parses the config every second: changes apply immediately, no restart needed.",
"groups": []
}
]
}
EOF
echo "Seeded default config at ${EASY_GATE_CONFIG_PATH}"
fi
exec /usr/local/bin/easy-gate
+6 -5
View File
@@ -9,9 +9,9 @@ The Cloudron component focuses on packaging upstream free/libre/open application
### 📊 Current Progress
- **Total Applications**: ~57 (see [GitUrlList.txt](GitUrlList.txt))
- **Completed Packages**: 9/~57 (~16%)
- **Completed Packages**: 10/~57 (~18%)
- **Packaging Templates**: Created ✅
- **Packages Committed & Pushed**: 9
- **Packages Committed & Pushed**: 10
- **Build Tickets**: 46 filed (#633-#678, umbrella
[#632](https://projects.knownelement.com/issues/632), Redmine project 55);
grist-core excluded (packaged upstream)
@@ -31,6 +31,7 @@ The Cloudron component focuses on packaging upstream free/libre/open application
| 7 | Corteza | Low-Code | 436MB | 80 | localstorage, postgresql | ✅ Committed |
| 8 | draw.io | Documentation-Tools | — | 8080 | none (auth proxy) | ✅ Committed |
| 9 | Windmill | Automation | ~2GB | 8000 | localstorage, postgresql | ✅ Committed |
| 10 | Easy-Gate | Infrastructure | 3.18GB | 8080 | localstorage (auth proxy) | ✅ Committed |
### 📦 Packages in Development
@@ -64,7 +65,7 @@ None currently in development.
### ⚡ Productivity Metrics
- **Packages Completed**: 9/~57 (~16%)
- **Packages Completed**: 10/~57 (~18%)
- **Average Package Time**: ~30 minutes
- **Success Rate**: 100% (all packages built successfully)
- **Commits Pushed**: 100% (all packages pushed to remote)
@@ -89,7 +90,7 @@ Applications are organized by function rather than programming language:
| **Documentation-Tools** | Documentation and diagramming tools | 3 | 1/3 (33%) |
| **Financial-Payments** | Payment processing and financial infrastructure | 1 | 0/1 (0%) |
| **Financial-Trading** | Trading and financial algorithm platforms | 1 | 0/1 (0%) |
| **Infrastructure** | Infrastructure and networking tools | 6 | 0/6 (0%) |
| **Infrastructure** | Infrastructure and networking tools | 6 | 1/6 (17%) |
| **Legal** | Legal and compliance applications | 1 | 0/1 (0%) |
| **Low-Code** | Low-code and no-code platforms | 3 | 1/3 (33%) |
| **Monitoring** | Monitoring and observability tools | 6 | 1/6 (17%) |
@@ -127,7 +128,7 @@ Applications are organized by function rather than programming language:
| [NetBox](https://github.com/netbox-community/netbox) | [GitHub](https://github.com/netbox-community/netbox) | IP address management (IPAM) and data center infrastructure management | Infrastructure |
| [SeaTunnel](https://github.com/apache/seatunnel) | [GitHub](https://github.com/apache/seatunnel) | Data integration and streaming platform | Data-Management |
| [Rathole](https://github.com/rapiz1/rathole) | [GitHub](https://github.com/rapiz1/rathole) | Lightweight and high-performance reverse proxy | Infrastructure |
| [Easy-Gate](https://github.com/wiredlush/easy-gate) | [GitHub](https://github.com/wiredlush/easy-gate) | Gateway and proxy solution | Infrastructure |
| [Easy-Gate](https://github.com/wiredlush/easy-gate) | [GitHub](https://github.com/wiredlush/easy-gate) | Gateway and proxy solution | Infrastructure | ✅ Packaged |
| [Huginn](https://github.com/huginn/huginn) | [GitHub](https://github.com/huginn/huginn) | Agents that do things for you automatically | Automation |
| [ConsulDemocracy](https://github.com/consuldemocracy/consuldemocracy) | [GitHub](https://github.com/consuldemocracy/consuldemocracy) | Open-source citizen participation platform | Collaboration |
| [BOINC](https://github.com/BOINC/boinc) | [GitHub](https://github.com/BOINC/boinc) | Open-source software for volunteer computing | Scientific-Computing |
+9 -7
View File
@@ -3,20 +3,20 @@
> **Human read-only. Agents maintain this file automatically after each work
> session.** Do not edit by hand — the next agent run will overwrite it.
>
> **Last updated:** 2026-09-01 by Crush (GLM-5.2) — 46 build tickets filed
> (#633-#678, umbrella #632, Redmine project 55); clone-repos.sh repaired
> and re-run; Cloudron redis-addon correction (NetBox re-rated viable).
> **Last updated:** 2026-09-01 by Crush (GLM-5.2) — Easy-Gate packaged
> (#651, Infrastructure, 10th package); auth gate verdict: no user concept,
> shipped behind the Cloudron auth proxy.
## Current State: STABLE (packaging phase, ongoing)
Cloudron packaging pipeline is operational. 9 of ~57 upstream applications are
Cloudron packaging pipeline is operational. 10 of ~57 upstream applications are
packaged, committed, and pushed. Packaging templates exist for the core
patterns. The gardening protocol (this file + AGENTS.md) keeps docs in sync.
All remaining apps now carry build tickets (#633-#678) under umbrella
[#632](https://projects.knownelement.com/issues/632) in Redmine project 55 —
ready for the sequential grind-driver pattern.
## Completed Packages (9)
## Completed Packages (10)
| # | Application | Category | Pattern | Port(s) | Addons |
|---|-------------|----------|---------|---------|--------|
@@ -29,6 +29,7 @@ ready for the sequential grind-driver pattern.
| 7 | Corteza | Low-Code | Pre-compiled binaries | 80 | localstorage, postgresql |
| 8 | draw.io | Documentation-Tools | Official-image wrapper + auth proxy | 8080 | none (stateless) |
| 9 | Windmill | Automation | Official-image wrapper + start.sh | 8000 | localstorage, postgresql |
| 10 | Easy-Gate | Infrastructure | Multi-stage (Go) + auth proxy | 8080 | localstorage |
Each package lives in `Package-Workspace/<Category>/<app>/` and contains a
`Dockerfile`, `CloudronManifest.json`, `README.md`, `CHANGELOG.md`, `logo.png`,
@@ -117,7 +118,7 @@ Full write-ups of each pattern + challenges are in [`JOURNAL.md`](JOURNAL.md).
| DevOps-Tools | 1 | 0/1 | |
| Financial-Payments | 1 | 0/1 | |
| Financial-Trading | 1 | 0/1 | |
| Infrastructure | 6 | 0/6 | |
| Infrastructure | 6 | 1/6 | easy-gate done |
| Legal | 1 | 0/1 | |
| Project-Management | 1 | 0/1 | |
| Scientific-Computing | 2 | 0/2 | |
@@ -131,7 +132,7 @@ Auth capability is a hard gate before packaging (see
LDAP acceptable (risk flag), 🔄 = auth-proxy (no users), ❌ = local-only
(unacceptable / blocked-on-auth).
### Completed packages (9)
### Completed packages (10)
| App | OIDC | LDAP | Verdict | Note |
|-----|------|------|---------|------|
@@ -144,6 +145,7 @@ LDAP acceptable (risk flag), 🔄 = auth-proxy (no users), ❌ = local-only
| Corteza | yes | no | ✅ preferred | Native OIDC via `auth.external.providers.openid-connect.*` |
| draw.io | n/a | n/a | 🔄 proxy | **Packaged** with `httpAuth.type=proxy` (no users, stateless) |
| Windmill | yes | no | ✅ preferred | **Packaged**; OIDC configured via Admin Settings UI (no env vars) |
| Easy-Gate | n/a | n/a | 🔄 proxy | **Packaged** with `httpAuth.type=proxy` (no user concept; IP-subnet groups only) |
### Candidates researched