01-guacamole.md
kstack: book: Centerpoint Home Lab chapter: Utilities page: Apache Guacamole tags: [guacamole, remote-desktop, rdp, vnc, ssh, authentik, postgres]
Overview
Apache Guacamole is a clientless remote desktop gateway. It provides browser-based
access to RDP, VNC, SSH, and Telnet sessions with no client software required.
Authentication is via Authentik OpenID Connect (native Guacamole extension — not
Traefik ForwardAuth). The stack is three containers: the web application, the
guacd native protocol daemon, and PostgreSQL 15 for connection and user data.
Access
| Type | URL | Auth |
|---|---|---|
| External | https://guac.jeeves5454.ddns.net |
Authentik OIDC + GeoBlock + CrowdSec |
| Internal | https://guac.home.local |
Authentik OIDC (Step-CA TLS) |
Guacamole uses its built-in openid extension with EXTENSION_PRIORITY=openid
to handle the Authentik OIDC flow directly. Traefik does not apply
authentik-auth@docker ForwardAuth.
Containers
| Container | Image | Role |
|---|---|---|
guacamole |
guacamole/guacamole:latest |
Web application (Tomcat/Java) |
guacd |
guacamole/guacd:latest |
Native protocol daemon (RDP/VNC/SSH) |
guacamole_db |
postgres:15-alpine |
PostgreSQL database |
guacamole (application)
Runtime: Apache Tomcat / Java. WEBAPP_CONTEXT=ROOT serves the app at /
rather than /guacamole.
Key environment variables:
| Variable | Value / Notes |
|---|---|
GUACD_HOSTNAME |
guacd |
POSTGRESQL_HOSTNAME |
postgres (internal alias for guacamole_db) |
POSTGRESQL_DATABASE |
guacamole_db |
POSTGRESQL_USER |
guacamole_user |
POSTGRESQL_PASSWORD |
REDACTED |
WEBAPP_CONTEXT |
ROOT |
EXTENSION_PRIORITY |
openid |
OPENID_ISSUER |
https://auth.jeevesconsults.ca/application/o/guacamole/ |
OPENID_CLIENT_ID |
A1l7KFyrugknbC8jtFjPxm520XkcNVjGMfTFtJMt |
OPENID_CLIENT_SECRET |
REDACTED |
OPENID_REDIRECT_URI |
https://guac.jeeves5454.ddns.net/ |
OPENID_AUTHORIZATION_ENDPOINT |
https://auth.jeevesconsults.ca/application/o/authorize/ |
OPENID_JWKS_ENDPOINT |
https://auth.jeevesconsults.ca/application/o/guacamole/jwks/ |
OPENID_SCOPE |
openid email profile |
OPENID_USERNAME_CLAIM_TYPE |
preferred_username |
No bind mounts — app state is stored in PostgreSQL.
guacd
The native protocol daemon that handles the actual RDP, VNC, SSH, and Telnet protocol sessions. Guacamole app proxies all protocol traffic through guacd.
Bind mounts:
| Host Path | Container Path | Purpose |
|---|---|---|
/home/jeeves/docker/guacamole/drive |
/drive |
Virtual drive for file transfer |
/home/jeeves/docker/guacamole/record |
/record |
Session recordings |
guacamole_db (PostgreSQL 15)
Image: postgres:15-alpine
| Variable | Value |
|---|---|
POSTGRES_DB |
guacamole_db |
POSTGRES_USER |
guacamole_user |
POSTGRES_PASSWORD |
REDACTED |
PGDATA |
/var/lib/postgresql/data/guacamole |
Bind mounts:
| Host Path | Container Path | Purpose |
|---|---|---|
/home/jeeves/docker/guacamole/db-data |
/var/lib/postgresql/data |
Database files |
/home/jeeves/docker/guacamole/init |
/docker-entrypoint-initdb.d |
Init SQL scripts |
Traefik Labels
traefik.http.routers.guacamole-external.rule: Host(`guac.jeeves5454.ddns.net`)
traefik.http.routers.guacamole-external.entrypoints: websecure
traefik.http.routers.guacamole-external.tls.certresolver: letsencrypt
traefik.http.routers.guacamole-external.middlewares: plex-geoblock@file,crowdsec-bouncer@file
traefik.http.routers.guacamole-external.service: guac-svc
traefik.http.routers.guacamole-internal.rule: Host(`guac.home.local`)
traefik.http.routers.guacamole-internal.entrypoints: websecure
traefik.http.routers.guacamole-internal.tls.certresolver: step-ca
traefik.http.routers.guacamole-internal.service: guac-svc
traefik.http.services.guac-svc.loadbalancer.server.port: 8080
traefik.docker.network: traefik-net
Notes / Gotchas
EXTENSION_PRIORITY=openidmeans Guacamole's OpenID extension takes precedence over any local user database. If Authentik is down, Guacamole login is unavailable — there is no local admin fallback while OpenID is primary.OPENID_REDIRECT_URImust exactly match the redirect URI registered in Authentik. It points to the external domain (guac.jeeves5454.ddns.net) even when accessing internally — Authentik sends the browser there after authentication.WEBAPP_CONTEXT=ROOTremoves the/guacamolepath prefix. The app responds directly at/. Without this, Traefik would need to strip the prefix or all URLs would be/guacamole/....- Session recordings are stored in the
recordbind mount. Manage disk usage if many long sessions are recorded. - The
initbind mount contains the SQL schema initialisation scripts for the database. These run once on first start. Do not remove them if the container has not yet initialised.
Last Updated: 2026-06-17
No comments to display
No comments to display