Add RustDesk server and Caddy HTTPS reverse proxy
Proxy forgejo/jellyfin/rustdesk info under devopshomelab.com with Let's Encrypt, publish RustDesk hbbs/hbbr ports, and wire Forgejo ROOT_URL to https://forgejo.devopshomelab.com.
This commit is contained in:
parent
1a6f915f04
commit
0ddf1d3699
5 changed files with 175 additions and 12 deletions
|
|
@ -173,8 +173,14 @@ ufw_allow_ssh_from_anywhere: false
|
|||
|
||||
ufw_lan_tcp_ports:
|
||||
- { port: 22, comment: "SSH" }
|
||||
- { port: 80, comment: "Landing (Caddy)" }
|
||||
- { port: 80, comment: "Caddy HTTP / ACME" }
|
||||
- { port: 443, comment: "Caddy HTTPS" }
|
||||
- { port: 8080, comment: "qBittorrent" }
|
||||
- { port: 21115, comment: "RustDesk" }
|
||||
- { port: 21116, comment: "RustDesk" }
|
||||
- { port: 21117, comment: "RustDesk relay" }
|
||||
- { port: 21118, comment: "RustDesk" }
|
||||
- { port: 21119, comment: "RustDesk" }
|
||||
- { port: 8096, comment: "Jellyfin" }
|
||||
- { port: 8989, comment: "Sonarr" }
|
||||
- { port: 7878, comment: "Radarr" }
|
||||
|
|
|
|||
|
|
@ -187,8 +187,11 @@ services:
|
|||
# devices:
|
||||
# - /dev/dri:/dev/dri
|
||||
|
||||
# ----------------------------------------------------- LAN landing (Caddy) #
|
||||
# Dark-mode map of services for other PCs on the network: http://server/
|
||||
# -------------------------------- Caddy: landing + HTTPS reverse proxy --- #
|
||||
# LAN map: http://192.168.8.123/
|
||||
# Public: https://forgejo.devopshomelab.com https://jellyfin.devopshomelab.com
|
||||
# https://rustdesk.devopshomelab.com (info page) https://devopshomelab.com
|
||||
# Let's Encrypt HTTP-01 needs WAN :80/:443 → this host and grey-cloud DNS.
|
||||
landing:
|
||||
image: caddy:2-alpine
|
||||
container_name: landing
|
||||
|
|
@ -196,9 +199,17 @@ services:
|
|||
networks: [arr-net]
|
||||
ports:
|
||||
- "${LANDING_PORT:-80}:80"
|
||||
- "${LANDING_HTTPS_PORT:-443}:443"
|
||||
environment:
|
||||
CADDY_EMAIL: ${CADDY_EMAIL:-admin@devopshomelab.com}
|
||||
volumes:
|
||||
- ./landing/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- ./landing/site:/srv:ro
|
||||
- ${CONFIG_DIR}/caddy-data:/data
|
||||
- ${CONFIG_DIR}/caddy-config:/config
|
||||
depends_on:
|
||||
- forgejo
|
||||
- jellyfin
|
||||
|
||||
# ---------------------------------------------- Cloudflare dynamic DNS (A) #
|
||||
# Updates apex + subdomains to the host's public IPv4. Secrets from secrets/.env
|
||||
|
|
@ -380,9 +391,10 @@ services:
|
|||
FORGEJO__server__START_SSH_SERVER: "false"
|
||||
FORGEJO__server__DISABLE_SSH: "false"
|
||||
FORGEJO__server__SSH_PORT: ${FORGEJO_SSH_PORT:-2222}
|
||||
FORGEJO__server__SSH_DOMAIN: ${FORGEJO_DOMAIN:-192.168.8.123}
|
||||
FORGEJO__server__DOMAIN: ${FORGEJO_DOMAIN:-192.168.8.123}
|
||||
FORGEJO__server__ROOT_URL: ${FORGEJO_ROOT_URL:-http://192.168.8.123:3002/}
|
||||
FORGEJO__server__SSH_DOMAIN: ${FORGEJO_DOMAIN:-forgejo.devopshomelab.com}
|
||||
FORGEJO__server__DOMAIN: ${FORGEJO_DOMAIN:-forgejo.devopshomelab.com}
|
||||
# Public HTTPS via Caddy (see landing/Caddyfile). LAN still works on :3002.
|
||||
FORGEJO__server__ROOT_URL: ${FORGEJO_ROOT_URL:-https://forgejo.devopshomelab.com/}
|
||||
FORGEJO__server__HTTP_PORT: "3000"
|
||||
# SQLite by default (no extra DB container)
|
||||
FORGEJO__database__DB_TYPE: sqlite3
|
||||
|
|
@ -392,6 +404,40 @@ services:
|
|||
- ${CONFIG_DIR}/forgejo:/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# RustDesk server (OSS) — rustdesk.devopshomelab.com
|
||||
# Clients use TCP/UDP 21115–21119 (not HTTP). Open those ports on the router.
|
||||
# Public key: docker exec rustdesk-hbbs cat /root/id_ed25519.pub
|
||||
# -------------------------------------------------------------------------
|
||||
rustdesk-hbbr:
|
||||
image: rustdesk/rustdesk-server:latest
|
||||
container_name: rustdesk-hbbr
|
||||
restart: unless-stopped
|
||||
networks: [arr-net]
|
||||
command: hbbr
|
||||
volumes:
|
||||
- ${CONFIG_DIR}/rustdesk:/root
|
||||
ports:
|
||||
- "21117:21117"
|
||||
- "21119:21119"
|
||||
|
||||
rustdesk-hbbs:
|
||||
image: rustdesk/rustdesk-server:latest
|
||||
container_name: rustdesk-hbbs
|
||||
restart: unless-stopped
|
||||
networks: [arr-net]
|
||||
# -r = relay host:port advertised to clients
|
||||
command: hbbs -r ${RUSTDESK_DOMAIN:-rustdesk.devopshomelab.com}:21117
|
||||
volumes:
|
||||
- ${CONFIG_DIR}/rustdesk:/root
|
||||
ports:
|
||||
- "21115:21115"
|
||||
- "21116:21116"
|
||||
- "21116:21116/udp"
|
||||
- "21118:21118"
|
||||
depends_on:
|
||||
- rustdesk-hbbr
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# OpenHands — always deployed (this stack always brings up every service)
|
||||
# UI: http://host:3001 · LLM via bonsai OpenAI API
|
||||
|
|
|
|||
|
|
@ -1,7 +1,81 @@
|
|||
# Homelab landing page — LAN only (UFW allows 80 from LAN)
|
||||
# Reverse proxy + LAN landing + automatic HTTPS (Let's Encrypt HTTP-01).
|
||||
#
|
||||
# Prerequisites:
|
||||
# 1. cloudflare-ddns points A records at this host's public IPv4
|
||||
# 2. Router port-forwards WAN :80 and :443 → this host
|
||||
# 3. DNS-only (grey cloud) for names used here — orange-cloud breaks HTTP-01 to origin
|
||||
# 4. Domain is devopshomelab.com (Cloudflare zone). If you meant .org, change all hostnames.
|
||||
#
|
||||
# Email for ACME registration (set in compose): CADDY_EMAIL
|
||||
|
||||
{
|
||||
email {$CADDY_EMAIL}
|
||||
}
|
||||
|
||||
# --- HTTPS reverse proxies ---------------------------------------------------
|
||||
|
||||
forgejo.devopshomelab.com {
|
||||
encode gzip
|
||||
reverse_proxy forgejo:3000
|
||||
}
|
||||
|
||||
jellyfin.devopshomelab.com {
|
||||
encode gzip
|
||||
reverse_proxy jellyfin:8096
|
||||
}
|
||||
|
||||
# Info page only — RustDesk clients use TCP/UDP 21115–21119, not this site
|
||||
rustdesk.devopshomelab.com {
|
||||
encode gzip
|
||||
header Content-Type "text/html; charset=utf-8"
|
||||
respond `<!DOCTYPE html><html><head><meta charset="utf-8"><title>RustDesk</title>
|
||||
<style>body{font-family:system-ui;background:#0c0e12;color:#e8ecf4;max-width:40rem;margin:3rem auto;padding:0 1rem;line-height:1.5}
|
||||
code{background:#1a1f2a;padding:.15rem .4rem;border-radius:4px;color:#6ea8fe}</style></head>
|
||||
<body>
|
||||
<h1>RustDesk server</h1>
|
||||
<p><strong>ID / rendezvous server:</strong> <code>rustdesk.devopshomelab.com</code></p>
|
||||
<p><strong>Relay server:</strong> <code>rustdesk.devopshomelab.com</code> (port <code>21117</code>)</p>
|
||||
<p>In the RustDesk client: Network → ID server = hostname above. Paste the server public key from the host admin.</p>
|
||||
<p>Open ports on the router/firewall: <code>21115–21119</code> TCP and <code>21116</code> UDP.</p>
|
||||
</body></html>` 200
|
||||
}
|
||||
|
||||
www.devopshomelab.com {
|
||||
redir https://devopshomelab.com{uri} permanent
|
||||
}
|
||||
|
||||
devopshomelab.com {
|
||||
encode gzip
|
||||
root * /srv
|
||||
file_server
|
||||
try_files {path} /index.html
|
||||
}
|
||||
|
||||
# --- HTTP :80 (ACME + LAN IP landing) ----------------------------------------
|
||||
|
||||
:80 {
|
||||
@lan {
|
||||
host 192.168.8.123 localhost 127.0.0.1
|
||||
}
|
||||
handle @lan {
|
||||
root * /srv
|
||||
encode gzip
|
||||
file_server
|
||||
try_files {path} /index.html
|
||||
}
|
||||
|
||||
@acme_hosts {
|
||||
host devopshomelab.com www.devopshomelab.com forgejo.devopshomelab.com jellyfin.devopshomelab.com rustdesk.devopshomelab.com
|
||||
}
|
||||
handle @acme_hosts {
|
||||
redir https://{host}{uri} permanent
|
||||
}
|
||||
|
||||
# Default: still serve the map (LAN hostname / other access)
|
||||
handle {
|
||||
root * /srv
|
||||
encode gzip
|
||||
file_server
|
||||
try_files {path} /index.html
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,10 @@ LAN URLs (UFW allows **`192.168.8.0/24`**). Replace host if needed.
|
|||
|---------|-----|
|
||||
| **Landing page** | http://192.168.8.123/ |
|
||||
| Cloudflare DDNS | (background) apex + subdomains → public IPv4 |
|
||||
| **Forgejo (HTTPS)** | https://forgejo.devopshomelab.com/ |
|
||||
| **Jellyfin (HTTPS)** | https://jellyfin.devopshomelab.com/ |
|
||||
| **RustDesk (info)** | https://rustdesk.devopshomelab.com/ |
|
||||
| RustDesk (client) | `rustdesk.devopshomelab.com` ports **21115–21119** |
|
||||
| Jellyfin | http://192.168.8.123:8096 |
|
||||
| qBittorrent | http://192.168.8.123:8080 |
|
||||
| Prowlarr | http://192.168.8.123:9696 |
|
||||
|
|
@ -183,12 +187,45 @@ Always edit **`secrets/.env`** first, then run only what you changed:
|
|||
|
||||
```bash
|
||||
cd /opt/stack
|
||||
# include rustdesk in CLOUDFLARESUBDOMAINS if missing
|
||||
./scripts/render-cloudflare-ddns-env.sh
|
||||
docker compose up -d cloudflare-ddns --force-recreate
|
||||
docker logs cloudflare-ddns --tail 30
|
||||
```
|
||||
|
||||
Needs: `CLOUDFLAREAPIKEY`, `CLOUDFLAREDOMAIN`, `CLOUDFLARESUBDOMAINS` (and optional `CLOUDFLARE_PROXIED`). Token: **Zone → DNS → Edit**. Default `PROXIED=false` (DNS-only; better for VPN).
|
||||
Needs: `CLOUDFLAREAPIKEY`, `CLOUDFLAREDOMAIN`, `CLOUDFLARESUBDOMAINS` (and optional `CLOUDFLARE_PROXIED`). Token: **Zone → DNS → Edit**. Default `PROXIED=false` (DNS-only; required for Let's Encrypt HTTP-01 and for VPN/RustDesk).
|
||||
|
||||
**HTTPS reverse proxy (Caddy + Let's Encrypt)**
|
||||
|
||||
Caddy (`landing` service) terminates TLS and routes:
|
||||
|
||||
| Hostname | Backend |
|
||||
|----------|---------|
|
||||
| `https://forgejo.devopshomelab.com` | `forgejo:3000` |
|
||||
| `https://jellyfin.devopshomelab.com` | `jellyfin:8096` |
|
||||
| `https://rustdesk.devopshomelab.com` | Info page only |
|
||||
| `https://devopshomelab.com` | LAN resource map |
|
||||
|
||||
```bash
|
||||
# 1) DNS A records must point here (DDNS) — grey cloud, not orange
|
||||
# 2) Router: forward WAN TCP 80 + 443 → 192.168.8.123
|
||||
# 3) UFW: allow 80/443 (playbook) + RustDesk 21115-21119 if remote clients
|
||||
docker compose up -d landing forgejo jellyfin
|
||||
docker logs landing --tail 40 # watch for certificate obtain
|
||||
```
|
||||
|
||||
Forgejo `ROOT_URL` is `https://forgejo.devopshomelab.com/` (set in compose/`.env`). LAN still works at `http://192.168.8.123:3002/`.
|
||||
|
||||
**RustDesk server**
|
||||
|
||||
```bash
|
||||
docker compose up -d rustdesk-hbbs rustdesk-hbbr
|
||||
# Public key for clients:
|
||||
docker exec rustdesk-hbbs cat /root/id_ed25519.pub
|
||||
```
|
||||
|
||||
Client settings: ID server = `rustdesk.devopshomelab.com`, key = pubkey above.
|
||||
Open on router/firewall: **21115–21119/tcp** and **21116/udp**.
|
||||
|
||||
**Usenet one-liner after secret edit:**
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ CLOUDFLAREZONEID=
|
|||
CLOUDFLAREACCOUNTID=
|
||||
CLOUDFLAREDOMAIN=devopshomelab.com
|
||||
# Comma-separated labels (or FQDNs). Apex is always included.
|
||||
CLOUDFLARESUBDOMAINS=mc,minecraft,vpn,www,forgejo,jellyfin
|
||||
# false = DNS-only (needed for VPN); true = orange-cloud proxy
|
||||
CLOUDFLARESUBDOMAINS=mc,minecraft,vpn,www,forgejo,jellyfin,rustdesk
|
||||
# false = DNS-only (required for Let's Encrypt HTTP-01 + VPN); true = orange-cloud proxy
|
||||
CLOUDFLARE_PROXIED=false
|
||||
CLOUDFLARE_UPDATE_CRON=@every 5m
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue