Skip to content

VPS

ItemDetail
HostnameWTSCPVM01
ProviderNetcup SCP
IP address152.53.226.118
OSDebian 13
Spec2 vCPU, 4 GB RAM
LocationGermany

The VPS runs two stacks: Pangolin (the reverse proxy and tunnel server) and Keycloak (identity provider). Both are managed via Docker Compose under /root/ and /opt/keycloak/ respectively.


Name Description Version URLs Status
Pangolin Self-hosted reverse proxy and tunnelling solution ee-1.16.2 https://pangolin.wighttrash.uk
running
Traefik Reverse proxy - TLS termination and routing 3.6 -
running
Gerbil WireGuard tunnel manager 1.3.0 -
running
Keycloak Identity and access management 26.4.7 https://auth.wighttrash.uk
running
PostgreSQL Keycloak database 16 -
running
  • Traefik: Shares network namespace with Gerbil.
  • Gerbil: Handles inbound ports 80, 443, 51820, 21820.
  • PostgreSQL: Internal only. Not exposed.

Cloudflare terminates TLS at the edge for all proxied records. Traffic arrives at the VPS on ports 80 and 443, enters through Gerbil, and is routed by Traefik. Keycloak runs on HTTP internally and is exposed via Traefik on port 8080.

flowchart TD INT([Internet]) CF["Cloudflare TLS for proxied records"] TR["Traefik - port 443 shares Gerbil network namespace"] GB["Gerbil WireGuard tunnel manager inbound 51820 and 21820"] TN["TrueNAS via Newt WireGuard tunnel"] PN["Pangolin frontend pangolin.wighttrash.uk"] KC["Keycloak auth.wighttrash.uk"] JF["Jellyfin media.wighttrash.uk"] IM["Immich photos.wighttrash.uk - DNS only"] INT --> CF CF -->|"*.wighttrash.uk → 152.53.226.118:443"| TR GB --> TR TR --> PN TR --> KC TR --> JF TR --> IM TN -->|"192.168.1.28:8096"| JF TN -->|"192.168.1.28:30041"| IM

/root/
├── docker-compose.yml <- Pangolin stack (pangolin, gerbil, traefik)
├── .env <- Cloudflare API token
├── config/
│ ├── config.yml <- Pangolin main config
│ ├── privateConfig.yml <- Enterprise Edition features
│ ├── traefik/
│ │ ├── traefik_config.yml
│ │ └── dynamic_config.yml
│ ├── letsencrypt/
│ │ └── acme.json
│ └── db/ <- Pangolin database
/opt/keycloak/
├── docker-compose.yml <- Keycloak stack (keycloak, postgres)
├── .env <- Keycloak secrets
└── Dockerfile <- Optimised build image

Terminal window
# Pangolin - full restart (always use down/up, never restart)
cd /root && docker compose down && docker compose up -d
# Pangolin - follow Traefik logs
cd /root && docker compose logs traefik --follow
# Keycloak - restart
cd /opt/keycloak && docker compose restart
# Keycloak - check health
curl -s http://localhost:9000/health/ready
# Check all containers
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

Managed via the Netcup SCP firewall panel. Rules are applied top to bottom with an implicit DROP on all unmatched traffic.

DescriptionDirectionProtocolPort
HTTPINCOMINGTCP80
HTTPSINCOMINGTCP443
WireGuard (Gerbil)INCOMINGUDP51820
WireGuard (Gerbil)INCOMINGUDP21820
SSHINCOMINGTCP22 (source-restricted)
HTTPS outboundOUTGOINGTCP443
HTTP outboundOUTGOINGTCP80
DNSOUTGOINGUDP53
Mail relayOUTGOINGTCP587
WireGuardOUTGOINGUDP51820, 21820
ICMPINCOMING + OUTGOINGICMP/ICMPv6*

SSH is restricted to a specific source IP.