The distributed reverse proxy that never sleeps.
One Go binary. Three personalities. API & MCP to automate infra.
Data plane, control plane and discovery in one Go binary — deploy the role you need, where you need it.
HTTP/1–3 QUIC, L4 TCP/UDP. Adaptive LB from Agent metrics, inter-Core gateway, failover. In-memory TLS, WS control hub, encrypted local cache.
Web UI (EN/FR/ES/DE), REST & MCP with scoped PAT. Domain delegation, error-page library, Access catalog & invites, multi-schedule backups, CLI (token/backup/alert/import).
Read-only docker.sock (or Podman). goproxify.* labels, K8s watch. Live container metrics over WS for adaptive LB. Routes applied on the Core in real time.
Each Core boots from an AES-256-GCM cache — autonomous without Admin. Raft Admin HA. Domain passthrough/terminate between Cores. Backend failover + quarantine.
OWASP CRS-4 WAF, rate limiting, Geo-IP, threat feeds. SSO / OIDC / SAML / LDAP / GitHub. Admin MFA. Security grade, Fail2Ban & CrowdSec. Scoped PAT for API & MCP.
JSON access logs, Prometheus, OpenTelemetry. Prism analytics (Admin + per-Core) with Logs correlation. Audit with session or PAT actor. Live traffic views.
Web terminal + standard ssh with UUID sessions. Admin catalog & invites, per-user vault (SSH login + key/password), optional 2FA, HTML templates with SPA fallback.
Three independent, complementary components. The Core is the source of truth — Admin is reconstructible; the Core never sleeps.
A ready-to-run Admin + Core + Agent stack. Pick your method.
Generates hex-32 secrets, writes .env (chmod 600), checks Docker / ports, then starts Admin + Core + Agent.
Official images on GHCR (SemVer + :preview). Pin tags from versions.json.
# Images (defaults = GHCR public) # GOPROXIFY_REGISTRY=ghcr.io/vincamok/goproxify # GOPROXIFY_ADMIN_TAG=0.2.29 # GOPROXIFY_CORE_TAG=0.3.18 # GOPROXIFY_AGENT_TAG=0.3.14 # Required GPX_JWT_SECRET= GPX_PAIRING_SECRET= GPX_FIRST_ADMIN_EMAIL=admin@example.com GPX_FIRST_ADMIN_PASSWORD= ADMIN_PORT=9443
Paste the compose, then load stack.env (Advanced → Load variables from .env file) or set the same keys in Environment variables.
# Portainer — model A: secrets via stack.env
networks:
goproxify_net:
name: goproxify_net
volumes:
goproxify_admin_data:
goproxify_core_data:
goproxify_agent_data:
services:
goproxify-admin:
image: ghcr.io/vincamok/goproxify/admin:0.2.29
container_name: goproxify-admin
restart: unless-stopped
command: ["admin"]
environment:
- TZ=${TZ:-Europe/Paris}
- GPX_SECURITY_JWT_SECRET=${GPX_JWT_SECRET}
- GPX_PAIRING_SECRET=${GPX_PAIRING_SECRET}
- GPX_FIRST_ADMIN_EMAIL=${GPX_FIRST_ADMIN_EMAIL}
- GPX_FIRST_ADMIN_PASSWORD=${GPX_FIRST_ADMIN_PASSWORD}
- GPX_IDENTITY_CORE_NODE_NAME=${CORE_NODE_NAME:-goproxify-core}
- GPX_SERVER_API_PORT=9443
ports:
- "${ADMIN_PORT:-9443}:9443"
volumes:
- goproxify_admin_data:/etc/goproxify
networks: [goproxify_net]
goproxify-core:
image: ghcr.io/vincamok/goproxify/core:0.3.18
container_name: goproxify-core
restart: unless-stopped
command: ["core"]
environment:
- TZ=${TZ:-Europe/Paris}
- GPX_PAIRING_SECRET=${GPX_PAIRING_SECRET}
- GPX_IDENTITY_CORE_NODE_NAME=${CORE_NODE_NAME:-goproxify-core}
ports:
- "${CORE_HTTP_PORT:-80}:80"
- "${CORE_HTTPS_PORT:-443}:443"
- "${CORE_HTTPS_PORT:-443}:443/udp"
volumes:
- goproxify_core_data:/etc/goproxify
networks: [goproxify_net]
depends_on: [goproxify-admin]
goproxify-agent:
image: ghcr.io/vincamok/goproxify/agent:0.3.14
container_name: goproxify-agent
restart: unless-stopped
command: ["agent"]
environment:
- TZ=${TZ:-Europe/Paris}
- GPX_PAIRING_SECRET=${GPX_PAIRING_SECRET}
- GPX_CONTROL_PLANE_CORE_ENDPOINT=http://goproxify-core:8000
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- goproxify_agent_data:/etc/goproxify
networks: [goproxify_net]
depends_on: [goproxify-core]
# Generate: bash quickstart.sh --print-secrets # or: openssl rand -hex 32 GPX_JWT_SECRET= GPX_PAIRING_SECRET= GPX_FIRST_ADMIN_EMAIL=admin@example.com GPX_FIRST_ADMIN_PASSWORD= ADMIN_PORT=9443 TZ=Europe/Paris CORE_NODE_NAME=goproxify-core
Single paste: replace CHANGE_ME_* before Deploy. No stack.env / env file needed.
# Portainer — model B: inline secrets (no stack.env) # Replace CHANGE_ME_* then Deploy the stack networks: goproxify_net: name: goproxify_net volumes: goproxify_admin_data: goproxify_core_data: goproxify_agent_data: services: goproxify-admin: image: ghcr.io/vincamok/goproxify/admin:0.2.29 container_name: goproxify-admin restart: unless-stopped command: ["admin"] environment: - TZ=Europe/Paris - GPX_SECURITY_JWT_SECRET=CHANGE_ME_JWT_HEX32 - GPX_PAIRING_SECRET=CHANGE_ME_PAIRING_HEX32 - GPX_FIRST_ADMIN_EMAIL=admin@example.com - GPX_FIRST_ADMIN_PASSWORD=CHANGE_ME_PASSWORD_MIN12 - GPX_IDENTITY_CORE_NODE_NAME=goproxify-core - GPX_SERVER_API_PORT=9443 ports: - "9443:9443" volumes: - goproxify_admin_data:/etc/goproxify networks: [goproxify_net] goproxify-core: image: ghcr.io/vincamok/goproxify/core:0.3.18 container_name: goproxify-core restart: unless-stopped command: ["core"] environment: - TZ=Europe/Paris - GPX_PAIRING_SECRET=CHANGE_ME_PAIRING_HEX32 - GPX_IDENTITY_CORE_NODE_NAME=goproxify-core ports: - "80:80" - "443:443" - "443:443/udp" volumes: - goproxify_core_data:/etc/goproxify networks: [goproxify_net] depends_on: [goproxify-admin] goproxify-agent: image: ghcr.io/vincamok/goproxify/agent:0.3.14 container_name: goproxify-agent restart: unless-stopped command: ["agent"] environment: - TZ=Europe/Paris - GPX_PAIRING_SECRET=CHANGE_ME_PAIRING_HEX32 - GPX_CONTROL_PLANE_CORE_ENDPOINT=http://goproxify-core:8000 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - goproxify_agent_data:/etc/goproxify networks: [goproxify_net] depends_on: [goproxify-core]
Each alert rule can notify multiple teams on multiple channels at once. Alertmanager-inspired model.
SMTP configurable
Slack, Discord, Teams…
Push mobile, self-hosted
Push mobile, self-hosted
Création d'issue auto
Issue tracking moderne
Ouverture d'issue
Ouverture d'issue
Ticketing open-source
ITSM, API REST
Deliberate choices. No heavy framework, no hidden runtime — just Go and proven libraries.
| Component | Role | Used in |
|---|---|---|
|
Go 1.25
|
Single static binary, zero runtime to install, native cross-compilation | Admin · Core · Agent |
|
HTTP/3 QUIC
|
UDP transport via quic-go. Automatic Alt-Svc, 0-RTT, lower latency on degraded networks |
Core |
|
SQLite (CGO-free)
|
Persistance without C deps. Cross-platform binary. Optional Raft cluster (3 nodes) for Admin HA | Admin |
|
WebSocket control plane
|
Persistent Admin↔Core and Agent↔Core tunnels. full_sync, live metrics for adaptive LB, inter-Core gateway |
Admin · Core · Agent |
|
Cache AES-256-GCM
|
Encrypted routes & certs on disk. Core starts autonomously even if Admin is unreachable | Core |
|
Prometheus
|
/metrics endpoint on every component — drop-in Grafana integration |
Admin · Core · Agent |
|
OpenTelemetry
|
Distributed request tracing. Configurable OTLP exporters (Jaeger, Tempo…) | Core · Admin |
|
Docker Engine API
|
Read-only via docker.sock. Real-time container events (start/stop/update) |
Agent |
|
JWT + PAT
|
UI session (JWT). User API tokens gpx_pat_* with scopes for REST & MCP. Separate Core/Agent pairing tokens |
Admin |
|
MCP
|
Model Context Protocol (JSON-RPC + SSE). Proxies, nodes, logs, audit tools… PAT required — Claude Desktop / Cursor ready | Admin |
|
ACME DNS-01
|
Automatic wildcard certs via OVH, Cloudflare, Gandi, Route53, Hetzner | Admin → Core |
Guides, API contract, MCP server and version tracking — all in the repo.
Endpoints, JWT / PAT auth, pairing tokens.
Claude Desktop, Cursor — plug in a gpx_pat_*.
Admin ↔ Core ↔ Agent flows, WS control plane, adaptive LB & gateway.
Passthrough vs Terminate between entry Core and target Core.