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:
+52
-1
@@ -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
@@ -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
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user