Skip to content

Apache Guacamole

Deploy Apache Guacamole on Kubernetes — a clientless remote desktop gateway that allows RDP, VNC, SSH, and Telnet access directly from a web browser with no client installation required.

Default credentials are guacadmin / guacadmin — change immediately after first login

Fresh Guacamole installations use guacadmin / guacadmin as the default administrator credentials. These are hardcoded in the schema SQL and well-known publicly. Change the password immediately after the first login via the Guacamole admin UI.

Key Features

  • guacd sidecar — protocol daemon runs alongside the web app, communicating on localhost:4822
  • Dual-image architectureguacamole (Tomcat web app) + guacd (protocol daemon)
  • PostgreSQL bundled by default — no extra setup for quick start
  • Schema init Job — automatic guacamole_db schema creation on install
  • OIDC, SAML, and TOTP — SSO and MFA integrations
  • Tomcat reverse proxy — correct client IP via X-Forwarded-For support
  • Database-aware backuppg_dump or mysqldump to S3

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install guacamole helmforge/guacamole -f values.yaml

OCI registry:

helm install guacamole oci://ghcr.io/helmforgedev/helm/guacamole -f values.yaml

Deployment Examples

# values.yaml — Guacamole with bundled PostgreSQL (default)
# Default credentials: guacadmin / guacadmin — CHANGE IMMEDIATELY after first login

guacd:
  logLevel: info

postgresql:
  enabled: true
  auth:
    database: guacamole_db
    username: guacamole_user
    password: 'strong-db-password'

ingress:
  enabled: true
  ingressClassName: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: remote.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: guacamole-tls
      hosts:
        - remote.example.com
# values.yaml — Guacamole with OIDC SSO (Keycloak example)
# OIDC replaces local database authentication for login
# redirectUri is auto-detected from ingress if left empty

oidc:
  enabled: true
  authorizationEndpoint: 'https://auth.example.com/realms/myrealm/protocol/openid-connect/auth'
  jwksEndpoint: 'https://auth.example.com/realms/myrealm/protocol/openid-connect/certs'
  issuer: 'https://auth.example.com/realms/myrealm'
  clientId: guacamole
  redirectUri: 'https://remote.example.com/' # auto-detected from ingress if empty
  scope: 'openid email profile'
  usernameClaim: preferred_username
  groupsClaim: groups

totp:
  enabled: true # combine OIDC with TOTP for 2FA on top of SSO

postgresql:
  enabled: true
  auth:
    password: 'strong-db-password'

ingress:
  enabled: true
  ingressClassName: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: remote.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: guacamole-tls
      hosts:
        - remote.example.com
# values.yaml — Guacamole with SAML SSO
saml:
  enabled: true
  idpMetadataUrl: 'https://auth.example.com/realms/myrealm/protocol/saml/descriptor'
  entityId: 'https://remote.example.com/'
  callbackUrl: 'https://remote.example.com/' # auto-detected from ingress if empty
  strict: true
  groupAttribute: groups

postgresql:
  enabled: true
  auth:
    password: 'strong-db-password'

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: remote.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Guacamole with external PostgreSQL and S3 backup
postgresql:
  enabled: false

mysql:
  enabled: false

database:
  type: postgresql
  external:
    host: postgres.database.svc.cluster.local
    port: 5432
    name: guacamole_db
    username: guacamole_user
    existingSecret: guacamole-db-credentials
    existingSecretPasswordKey: password

backup:
  enabled: true
  schedule: '0 2 * * *'
  s3:
    endpoint: https://s3.amazonaws.com
    bucket: guacamole-backups
    existingSecret: guacamole-s3-credentials

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: remote.example.com
      paths:
        - path: /
          pathType: Prefix

Configuration Reference

Images

ParameterTypeDefaultDescription
image.repositorystringdocker.io/guacamole/guacamoleGuacamole web app image.
image.tagstring"1.6.0"Image tag.
guacd.image.repositorystringdocker.io/guacamole/guacdguacd protocol daemon image.
guacd.image.tagstring"1.6.0"guacd image tag.

Guacamole

ParameterTypeDefaultDescription
guacamole.contextPathstringROOTWeb context path. ROOT = serve at /. Change to guacamole for /guacamole/.
guacamole.extraEnvarray[]Extra environment variables.
guacd.portinteger4822Internal guacd daemon port.
guacd.logLevelstringinfoguacd log level: info, debug, warning, error.

Reverse Proxy

ParameterTypeDefaultDescription
proxy.enabledbooleantrueEnable Tomcat RemoteIpValve for correct client IPs.
proxy.ipHeaderstringX-Forwarded-ForHeader containing the real client IP.
proxy.protocolHeaderstringX-Forwarded-ProtoHeader containing the protocol (http/https).

OIDC

ParameterTypeDefaultDescription
oidc.enabledbooleanfalseEnable OIDC SSO.
oidc.authorizationEndpointstring""OIDC authorization endpoint URL.
oidc.jwksEndpointstring""JWKS token validation endpoint URL.
oidc.issuerstring""Expected token issuer.
oidc.clientIdstring""OIDC client ID.
oidc.redirectUristring""Redirect URI. Auto-detected from ingress if empty.
oidc.usernameClaimstringpreferred_usernameJWT claim for the username.
oidc.groupsClaimstringgroupsJWT claim for groups.

SAML

ParameterTypeDefaultDescription
saml.enabledbooleanfalseEnable SAML SSO.
saml.idpMetadataUrlstring""IdP SAML metadata URL.
saml.entityIdstring""Service provider entity ID.
saml.callbackUrlstring""Callback URL. Auto-detected from ingress if empty.
saml.strictbooleantrueEnforce certificate validation.
saml.groupAttributestringgroupsSAML group attribute name.
totp.enabledbooleanfalseEnable TOTP two-factor authentication.

Database and Init Job

ParameterTypeDefaultDescription
database.typestringpostgresqlDatabase type: postgresql or mysql.
database.external.hoststring""External database hostname.
database.external.existingSecretstring""Existing secret with database password.
initDb.enabledbooleantrueRun schema init Job on install (safe for upgrades).
postgresql.enabledbooleantrueDeploy the bundled PostgreSQL subchart.
postgresql.auth.passwordstring""Password. Required when using the subchart.
mysql.enabledbooleanfalseDeploy the bundled MySQL subchart.

Service and Ingress

ParameterTypeDefaultDescription
service.typestringClusterIPService type.
service.portinteger80Service port.
ingress.enabledbooleanfalseEnable an Ingress resource.
ingress.ingressClassNamestringtraefikIngress class name.

Backup

Database-aware: pg_dump for PostgreSQL, mysqldump for MySQL.

ParameterTypeDefaultDescription
backup.enabledbooleanfalseEnable scheduled database S3 backup.
backup.schedulestring"0 2 * * *"Cron schedule.
backup.s3.endpointstring""S3-compatible endpoint URL.
backup.s3.bucketstring""Target bucket name.
backup.s3.existingSecretstring""Existing secret with S3 credentials.
extraManifestsarray[]Extra Kubernetes manifests.

More Information