# Apache Guacamole 1.6.0: a remote desktop (RDP, VNC, SSH) in a browser tab, behind Cloudflare Access. # # Kit template for guide doc 1 (layer L1) and doc 2 (build step "Guacamole"). Checked against the # Guacamole 1.6.0 manual as of October 2026. # # Before the first start, create the database schema (run in this folder): # mkdir -p init && docker run --rm guacamole/guacamole:1.6.0 /opt/guacamole/bin/initdb.sh --postgresql > init/initdb.sql # # Secrets in ./.env (chmod 600), created on the server by you: # POSTGRES_PASSWORD= # # Sign-in: Cloudflare Access adds the signed-in email in a request header, and Guacamole's header # authentication trusts it. That is safe ONLY because: # 1. the web app listens on 127.0.0.1, so nothing but the local tunnel can reach it, and # 2. the tunnel route has "Protect with Access" (access.required: true), so cloudflared rejects # requests without a valid Access token. # If either is missing, anyone who can reach the port can type the header and sign in as you. # The 1.6.0 variable names are HTTP_AUTH_ENABLED and HTTP_AUTH_HEADER. The 1.5 name HEADER_ENABLED is # ignored by 1.6.0. The schema creates a default guacadmin account: change its password or disable it # right after the first sign-in. name: guacamole services: guacd: image: guacamole/guacd:1.6.0 restart: unless-stopped networks: [guac, desktops] db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: guacamole POSTGRES_USER: guacamole POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set in .env} volumes: - ./db:/var/lib/postgresql/data - ./init:/docker-entrypoint-initdb.d:ro networks: [guac] healthcheck: test: ["CMD-SHELL", "pg_isready -U guacamole -d guacamole"] interval: 10s timeout: 5s retries: 20 guacamole: image: guacamole/guacamole:1.6.0 restart: unless-stopped depends_on: guacd: { condition: service_started } db: { condition: service_healthy } environment: GUACD_HOSTNAME: guacd POSTGRESQL_HOSTNAME: db POSTGRESQL_DATABASE: guacamole POSTGRESQL_USERNAME: guacamole POSTGRESQL_PASSWORD: ${POSTGRES_PASSWORD:?set in .env} POSTGRESQL_AUTO_CREATE_ACCOUNTS: "true" # an Access-approved email gets an account on first visit HTTP_AUTH_ENABLED: "true" HTTP_AUTH_HEADER: Cf-Access-Authenticated-User-Email WEBAPP_CONTEXT: ROOT # serve at / instead of /guacamole/ API_SESSION_TIMEOUT: "300" # minutes of inactivity before Guacamole signs you out ports: - "127.0.0.1:8007:8080" networks: [guac] networks: guac: {} desktops: # The network your desktop VM or container is on, so guacd can reach its RDP or VNC port. # Create it with: docker network create desktops external: true name: desktops