Skip to main content

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=openid means 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_URI must 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=ROOT removes the /guacamole path 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 record bind mount. Manage disk usage if many long sessions are recorded.
  • The init bind 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