Apache Guacamole Remote Desktop
Clientless remote desktop gateway supporting VNC, RDP, and SSH.
Overview
Apache Guacamole is a clientless remote desktop gateway that enables access to desktop environments through a web browser. Originally developed by the Apache Software Foundation, Guacamole eliminates the need for client-side software by implementing remote desktop protocols (VNC, RDP, SSH) through HTML5 and JavaScript, making it accessible from any device with a modern web browser. This deployment creates a complete four-tier architecture with guacd (the native proxy daemon), the Guacamole web application, PostgreSQL for user authentication and connection management, and NGINX as a reverse proxy for enhanced security and performance. The stack provides enterprise-grade remote access capabilities with features like session recording, file transfer, two-factor authentication via TOTP, and comprehensive user management through a web-based administration interface. This configuration is ideal for organizations implementing zero-trust remote access, managed service providers offering hosted desktop solutions, educational institutions providing lab access, and IT teams requiring secure administrative access to infrastructure without exposing RDP or SSH directly to the internet.
Key Features
- Protocol-agnostic remote access supporting VNC, RDP, SSH, and Telnet connections through a single web interface
- Built-in TOTP two-factor authentication for enhanced security and compliance requirements
- Session recording capabilities with dedicated storage volumes for audit trails and compliance
- File transfer support between client browsers and remote systems through the guacd proxy daemon
- PostgreSQL-backed user management with role-based access control and connection sharing
- Multi-protocol connection gateway allowing different remote desktop technologies from one portal
- NGINX reverse proxy providing SSL termination, load balancing, and protection against direct application exposure
- Persistent connection state management enabling session resumption and connection pooling
Common Use Cases
- 1Remote work infrastructure providing secure browser-based access to corporate desktops and servers
- 2Managed service provider offerings for hosted virtual desktop infrastructure (VDI) solutions
- 3Educational computer labs accessible remotely without requiring software installation on student devices
- 4IT administration portal for secure server management without exposing SSH or RDP ports publicly
- 5Development environment access for distributed teams working on shared development servers
- 6Customer support systems allowing technicians to access client systems through controlled gateway
- 7Compliance-focused environments requiring session recording and centralized access logging
Prerequisites
- Minimum 2GB RAM recommended for full stack operation with PostgreSQL and concurrent user sessions
- Docker host with port 8080 available for NGINX reverse proxy access
- Generated PostgreSQL initialization script (initdb.sql) containing Guacamole database schema
- Understanding of remote desktop protocols (VNC, RDP, SSH) and target system configuration
- Network access from Docker host to target remote desktop systems
- SSL certificates for production deployment with sensitive remote access
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 guacamole: 3 image: guacamole/guacamole:latest4 container_name: guacamole5 environment: 6 - GUACD_HOSTNAME=guacd7 - POSTGRESQL_HOSTNAME=db8 - POSTGRESQL_DATABASE=guacamole_db9 - POSTGRESQL_USER=guacamole10 - POSTGRESQL_PASSWORD=${DB_PASSWORD}11 - TOTP_ENABLED=true12 depends_on: 13 - guacd14 - db15 networks: 16 - guacamole-network17 restart: unless-stopped1819 guacd: 20 image: guacamole/guacd:latest21 container_name: guacd22 volumes: 23 - guacd-drive:/drive:rw24 - guacd-record:/record:rw25 networks: 26 - guacamole-network27 restart: unless-stopped2829 db: 30 image: postgres:15-alpine31 container_name: guacamole-db32 environment: 33 - POSTGRES_USER=guacamole34 - POSTGRES_PASSWORD=${DB_PASSWORD}35 - POSTGRES_DB=guacamole_db36 volumes: 37 - postgres-data:/var/lib/postgresql/data38 - ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql39 networks: 40 - guacamole-network41 restart: unless-stopped4243 nginx: 44 image: nginx:alpine45 container_name: guacamole-nginx46 ports: 47 - "8080:80"48 volumes: 49 - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro50 depends_on: 51 - guacamole52 networks: 53 - guacamole-network54 restart: unless-stopped5556volumes: 57 guacd-drive: 58 guacd-record: 59 postgres-data: 6061networks: 62 guacamole-network: 63 driver: bridge.env Template
.env
1# Apache Guacamole2DB_PASSWORD=secure_guacamole_password34# Generate initdb.sql with:5# docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > initdb.sqlUsage Notes
- 1Web UI at http://localhost:8080/guacamole
- 2Default login: guacadmin/guacadmin
- 3Generate initdb.sql before first run
- 4Supports VNC, RDP, SSH, Telnet
- 5Enable TOTP for 2FA security
Individual Services(4 services)
Copy individual services to mix and match with your existing compose files.
guacamole
guacamole:
image: guacamole/guacamole:latest
container_name: guacamole
environment:
- GUACD_HOSTNAME=guacd
- POSTGRESQL_HOSTNAME=db
- POSTGRESQL_DATABASE=guacamole_db
- POSTGRESQL_USER=guacamole
- POSTGRESQL_PASSWORD=${DB_PASSWORD}
- TOTP_ENABLED=true
depends_on:
- guacd
- db
networks:
- guacamole-network
restart: unless-stopped
guacd
guacd:
image: guacamole/guacd:latest
container_name: guacd
volumes:
- guacd-drive:/drive:rw
- guacd-record:/record:rw
networks:
- guacamole-network
restart: unless-stopped
db
db:
image: postgres:15-alpine
container_name: guacamole-db
environment:
- POSTGRES_USER=guacamole
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=guacamole_db
volumes:
- postgres-data:/var/lib/postgresql/data
- ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql
networks:
- guacamole-network
restart: unless-stopped
nginx
nginx:
image: nginx:alpine
container_name: guacamole-nginx
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- guacamole
networks:
- guacamole-network
restart: unless-stopped
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 guacamole:5 image: guacamole/guacamole:latest6 container_name: guacamole7 environment:8 - GUACD_HOSTNAME=guacd9 - POSTGRESQL_HOSTNAME=db10 - POSTGRESQL_DATABASE=guacamole_db11 - POSTGRESQL_USER=guacamole12 - POSTGRESQL_PASSWORD=${DB_PASSWORD}13 - TOTP_ENABLED=true14 depends_on:15 - guacd16 - db17 networks:18 - guacamole-network19 restart: unless-stopped2021 guacd:22 image: guacamole/guacd:latest23 container_name: guacd24 volumes:25 - guacd-drive:/drive:rw26 - guacd-record:/record:rw27 networks:28 - guacamole-network29 restart: unless-stopped3031 db:32 image: postgres:15-alpine33 container_name: guacamole-db34 environment:35 - POSTGRES_USER=guacamole36 - POSTGRES_PASSWORD=${DB_PASSWORD}37 - POSTGRES_DB=guacamole_db38 volumes:39 - postgres-data:/var/lib/postgresql/data40 - ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql41 networks:42 - guacamole-network43 restart: unless-stopped4445 nginx:46 image: nginx:alpine47 container_name: guacamole-nginx48 ports:49 - "8080:80"50 volumes:51 - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro52 depends_on:53 - guacamole54 networks:55 - guacamole-network56 restart: unless-stopped5758volumes:59 guacd-drive:60 guacd-record:61 postgres-data:6263networks:64 guacamole-network:65 driver: bridge66EOF6768# 2. Create the .env file69cat > .env << 'EOF'70# Apache Guacamole71DB_PASSWORD=secure_guacamole_password7273# Generate initdb.sql with:74# docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql75EOF7677# 3. Start the services78docker compose up -d7980# 4. View logs81docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/apache-guacamole/run | bashTroubleshooting
- guacamole container fails to start: Verify DB_PASSWORD environment variable is set and PostgreSQL service is healthy
- Cannot connect to remote desktop: Check that guacd container has network access to target systems and protocols are properly configured
- Database connection errors: Ensure initdb.sql schema is loaded and PostgreSQL container has sufficient memory allocated
- Session recordings not saving: Verify guacd-record volume is properly mounted and container has write permissions
- NGINX 502 Bad Gateway: Check that guacamole service is running and accessible on guacamole-network
- TOTP authentication not working: Verify system clocks are synchronized between Guacamole server and authentication devices
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
guacamoleguacdpostgresqlnginx
Tags
#remote-desktop#vnc#rdp#ssh#guacamole
Category
Security & NetworkingAd Space
Shortcuts: C CopyF FavoriteD Download