docker.recipes

Apache Guacamole Remote Desktop

intermediate

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:latest
4 container_name: guacamole
5 environment:
6 - GUACD_HOSTNAME=guacd
7 - POSTGRESQL_HOSTNAME=db
8 - POSTGRESQL_DATABASE=guacamole_db
9 - POSTGRESQL_USER=guacamole
10 - POSTGRESQL_PASSWORD=${DB_PASSWORD}
11 - TOTP_ENABLED=true
12 depends_on:
13 - guacd
14 - db
15 networks:
16 - guacamole-network
17 restart: unless-stopped
18
19 guacd:
20 image: guacamole/guacd:latest
21 container_name: guacd
22 volumes:
23 - guacd-drive:/drive:rw
24 - guacd-record:/record:rw
25 networks:
26 - guacamole-network
27 restart: unless-stopped
28
29 db:
30 image: postgres:15-alpine
31 container_name: guacamole-db
32 environment:
33 - POSTGRES_USER=guacamole
34 - POSTGRES_PASSWORD=${DB_PASSWORD}
35 - POSTGRES_DB=guacamole_db
36 volumes:
37 - postgres-data:/var/lib/postgresql/data
38 - ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql
39 networks:
40 - guacamole-network
41 restart: unless-stopped
42
43 nginx:
44 image: nginx:alpine
45 container_name: guacamole-nginx
46 ports:
47 - "8080:80"
48 volumes:
49 - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
50 depends_on:
51 - guacamole
52 networks:
53 - guacamole-network
54 restart: unless-stopped
55
56volumes:
57 guacd-drive:
58 guacd-record:
59 postgres-data:
60
61networks:
62 guacamole-network:
63 driver: bridge

.env Template

.env
1# Apache Guacamole
2DB_PASSWORD=secure_guacamole_password
3
4# Generate initdb.sql with:
5# docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql

Usage Notes

  1. 1Web UI at http://localhost:8080/guacamole
  2. 2Default login: guacadmin/guacadmin
  3. 3Generate initdb.sql before first run
  4. 4Supports VNC, RDP, SSH, Telnet
  5. 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 file
2cat > docker-compose.yml << 'EOF'
3services:
4 guacamole:
5 image: guacamole/guacamole:latest
6 container_name: guacamole
7 environment:
8 - GUACD_HOSTNAME=guacd
9 - POSTGRESQL_HOSTNAME=db
10 - POSTGRESQL_DATABASE=guacamole_db
11 - POSTGRESQL_USER=guacamole
12 - POSTGRESQL_PASSWORD=${DB_PASSWORD}
13 - TOTP_ENABLED=true
14 depends_on:
15 - guacd
16 - db
17 networks:
18 - guacamole-network
19 restart: unless-stopped
20
21 guacd:
22 image: guacamole/guacd:latest
23 container_name: guacd
24 volumes:
25 - guacd-drive:/drive:rw
26 - guacd-record:/record:rw
27 networks:
28 - guacamole-network
29 restart: unless-stopped
30
31 db:
32 image: postgres:15-alpine
33 container_name: guacamole-db
34 environment:
35 - POSTGRES_USER=guacamole
36 - POSTGRES_PASSWORD=${DB_PASSWORD}
37 - POSTGRES_DB=guacamole_db
38 volumes:
39 - postgres-data:/var/lib/postgresql/data
40 - ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql
41 networks:
42 - guacamole-network
43 restart: unless-stopped
44
45 nginx:
46 image: nginx:alpine
47 container_name: guacamole-nginx
48 ports:
49 - "8080:80"
50 volumes:
51 - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
52 depends_on:
53 - guacamole
54 networks:
55 - guacamole-network
56 restart: unless-stopped
57
58volumes:
59 guacd-drive:
60 guacd-record:
61 postgres-data:
62
63networks:
64 guacamole-network:
65 driver: bridge
66EOF
67
68# 2. Create the .env file
69cat > .env << 'EOF'
70# Apache Guacamole
71DB_PASSWORD=secure_guacamole_password
72
73# Generate initdb.sql with:
74# docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql
75EOF
76
77# 3. Start the services
78docker compose up -d
79
80# 4. View logs
81docker compose logs -f

One-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 | bash

Troubleshooting

  • 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

Ad Space