Add homelab installer and services (allprox, authelia, lldap)
This commit is contained in:
parent
68b23f1cbe
commit
bb754cdd8c
32 changed files with 2356 additions and 1 deletions
63
services/allprox/Caddyfile
Normal file
63
services/allprox/Caddyfile
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# allprox — Caddy reverse proxy
|
||||
#
|
||||
# Maps domains to local IPs and hosts an authenticated portal (web UI).
|
||||
# Edit the domain names below to match your DNS, and set the upstream
|
||||
# IP:port values in the installer's .env (APP1_UPSTREAM, APP2_UPSTREAM, ...).
|
||||
# Duplicate a "Proxied services" block to add more services.
|
||||
#
|
||||
# Authentication:
|
||||
# * Today: basic_auth (a single admin account; hash set via PORTAL_AUTH_HASH).
|
||||
# * Later: Authelia SSO — replace the basic_auth blocks with the forward_auth
|
||||
# block shown below (see https://www.authelia.com/integration/proxies/caddy/).
|
||||
|
||||
{
|
||||
# For public domains with automatic HTTPS, set your ACME email here:
|
||||
# email you@example.com
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Web UI — authenticated portal (change the domain to your own)
|
||||
# ---------------------------------------------------------------------------
|
||||
portal.example.com {
|
||||
# `tls internal` issues a self-signed cert for LAN use. Remove this line
|
||||
# and set the ACME email above when exposing a real public domain.
|
||||
tls internal
|
||||
|
||||
basic_auth {
|
||||
admin {$PORTAL_AUTH_HASH}
|
||||
}
|
||||
|
||||
# Authelia SSO (later): replace the basic_auth block above with:
|
||||
# forward_auth authelia:9091 {
|
||||
# uri /api/authz/forward-auth
|
||||
# copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
|
||||
# }
|
||||
|
||||
root * /srv/portal
|
||||
file_server
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Authelia portal — the SSO login page (proxy to the authelia container).
|
||||
# With Authelia running, users are redirected here to sign in.
|
||||
# ---------------------------------------------------------------------------
|
||||
auth.example.com {
|
||||
tls internal
|
||||
reverse_proxy authelia:9091
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Proxied services — copy a block per service. The local IP:port comes from
|
||||
# the {$APPx_UPSTREAM} variable in .env.
|
||||
# ---------------------------------------------------------------------------
|
||||
app1.example.com {
|
||||
tls internal
|
||||
# basic_auth { admin {$PORTAL_AUTH_HASH} } # or the Authelia forward_auth block
|
||||
reverse_proxy {$APP1_UPSTREAM}
|
||||
}
|
||||
|
||||
app2.example.com {
|
||||
tls internal
|
||||
# basic_auth { admin {$PORTAL_AUTH_HASH} }
|
||||
reverse_proxy {$APP2_UPSTREAM}
|
||||
}
|
||||
64
services/allprox/metadata.json
Normal file
64
services/allprox/metadata.json
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"id": "allprox",
|
||||
"name": "allprox",
|
||||
"description": "Caddy reverse proxy that routes domains to local IPs, hosts an authenticated portal (web UI), and is SSO-ready for Authelia (OAuth2/OIDC).",
|
||||
"version": "1.0.0",
|
||||
"category": "network",
|
||||
"tags": ["reverse-proxy", "caddy", "authelia", "sso", "https"],
|
||||
"author": "Caddy / Authelia",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://caddyserver.com",
|
||||
"documentation": "https://www.authelia.com/integration/proxies/caddy/",
|
||||
"compose": {
|
||||
"image": "caddy:2-alpine",
|
||||
"container_name": "allprox",
|
||||
"restart": "unless-stopped",
|
||||
"ports": ["80:80", "443:443", "443:443/udp"],
|
||||
"volumes": [
|
||||
"./Caddyfile:/etc/caddy/Caddyfile:ro",
|
||||
"./portal:/srv/portal:ro",
|
||||
"allprox_data:/data",
|
||||
"allprox_config:/config"
|
||||
],
|
||||
"environment": [
|
||||
"APP1_UPSTREAM=${APP1_UPSTREAM}",
|
||||
"APP2_UPSTREAM=${APP2_UPSTREAM}",
|
||||
"PORTAL_AUTH_HASH=${PORTAL_AUTH_HASH}"
|
||||
],
|
||||
"networks": ["homelab"]
|
||||
},
|
||||
"volumes": {
|
||||
"allprox_data": {},
|
||||
"allprox_config": {}
|
||||
},
|
||||
"networks": {
|
||||
"homelab": { "external": true }
|
||||
},
|
||||
"env": [
|
||||
{
|
||||
"name": "PORTAL_AUTH_HASH",
|
||||
"label": "Portal admin password (bcrypt hash)",
|
||||
"description": "bcrypt hash for basic_auth (default is 'changeme'). Generate your own with: docker compose exec allprox caddy hash-password",
|
||||
"default": "$2b$10$fKkpKSlwLZtOBXpInl8pG.8mS65kiEfjOVsuvBj7ikHgtfqEa7h4y",
|
||||
"required": false,
|
||||
"secret": true
|
||||
},
|
||||
{
|
||||
"name": "APP1_UPSTREAM",
|
||||
"label": "Upstream for app1.example.com",
|
||||
"description": "Local IP:port to proxy app1.example.com to",
|
||||
"default": "127.0.0.1:3000",
|
||||
"required": false,
|
||||
"secret": false
|
||||
},
|
||||
{
|
||||
"name": "APP2_UPSTREAM",
|
||||
"label": "Upstream for app2.example.com",
|
||||
"description": "Local IP:port to proxy app2.example.com to",
|
||||
"default": "127.0.0.1:8080",
|
||||
"required": false,
|
||||
"secret": false
|
||||
}
|
||||
],
|
||||
"notes": "Edit services/allprox/Caddyfile to add domains and change upstreams. The portal (web UI) is at portal.example.com (change the domain). Interim auth is basic_auth (admin / 'changeme' by default) — swap to the Authelia forward_auth block in the Caddyfile for OAuth2/OIDC SSO."
|
||||
}
|
||||
80
services/allprox/portal/index.html
Normal file
80
services/allprox/portal/index.html
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>allprox — portal</title>
|
||||
<style>
|
||||
:root { color-scheme: dark; }
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
||||
background: #0f172a;
|
||||
color: #e2e8f0;
|
||||
margin: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
main { width: 100%; max-width: 680px; padding: 2rem; }
|
||||
h1 { font-size: 2rem; margin: 0 0 .25rem; letter-spacing: -.02em; }
|
||||
.muted { color: #94a3b8; }
|
||||
.card {
|
||||
background: #1e293b;
|
||||
border: 1px solid #334155;
|
||||
border-radius: 12px;
|
||||
padding: 1.1rem 1.35rem;
|
||||
margin: 1.25rem 0;
|
||||
}
|
||||
.card strong { display: block; margin-bottom: .25rem; }
|
||||
ul { list-style: none; padding: 0; margin: 0; }
|
||||
li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: .55rem 0;
|
||||
border-bottom: 1px solid #334155;
|
||||
}
|
||||
li:last-child { border-bottom: none; }
|
||||
a { color: #7dd3fc; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
code {
|
||||
background: #0b1220;
|
||||
padding: .15rem .45rem;
|
||||
border-radius: 5px;
|
||||
font-size: .85em;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
.badge {
|
||||
font-size: .7rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .06em;
|
||||
color: #86efac;
|
||||
border: 1px solid #166534;
|
||||
background: #052e16;
|
||||
padding: .15rem .5rem;
|
||||
border-radius: 999px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>allprox <span class="badge">signed in</span></h1>
|
||||
<p class="muted">Authenticated access portal — you are signed in.</p>
|
||||
|
||||
<div class="card">
|
||||
<strong>Services</strong>
|
||||
<ul>
|
||||
<li><a href="https://app1.example.com">app1.example.com</a> <code>127.0.0.1:3000</code></li>
|
||||
<li><a href="https://app2.example.com">app2.example.com</a> <code>127.0.0.1:8080</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p class="muted">
|
||||
Edit this page at <code>services/allprox/portal/index.html</code> and the proxy
|
||||
rules in <code>services/allprox/Caddyfile</code>.
|
||||
</p>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue