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
@@ -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