Deploying Apache Guacamole
Introduction
Apache Guacamole is a clientless remote desktop gateway that supports standard protocols like VNC, RDP, and SSH. Unlike traditional remote desktop solutions that require client software installation, Guacamole is accessed entirely through a web browser, making it incredibly convenient and accessible from any device.
Guacamole is renowned for:
- Clientless Architecture: No plugins or client software required—access remote desktops through any modern web browser
- Multi-Protocol Support: Connect to VNC, RDP, SSH, Kubernetes, and Telnet servers from a single interface
- Centralized Access: Manage all remote connections through one unified web portal
- Session Recording: Record and replay remote desktop sessions for compliance and training
- Two-Factor Authentication: Enhanced security with support for TOTP, RADIUS, and other 2FA methods
- File Transfer: Upload and download files seamlessly during remote sessions
- Screen Sharing: Share your screen with multiple users simultaneously
- Mobile Friendly: Fully responsive interface works on tablets and smartphones
- Active Directory Integration: Authenticate users against LDAP, Active Directory, or database backends
Common use cases include IT support and helpdesk operations, remote server administration, secure access to development environments, cloud workspace management, and providing remote access for distributed teams.
This comprehensive guide walks you through deploying Apache Guacamole on Klutch.sh using Docker, including detailed installation steps, sample Dockerfile configurations, persistent storage setup, and production-ready best practices for secure remote desktop gateway deployment.
Prerequisites
Before you begin, ensure you have the following:
- A Klutch.sh account
- A GitHub account with a repository for your Guacamole project
- Docker installed locally for testing (optional but recommended)
- Basic understanding of Docker and remote desktop protocols (VNC/RDP/SSH)
- (Recommended) A PostgreSQL or MySQL database for production deployments
Installation and Setup
Step 1: Create Your Project Directory
First, create a new directory for your Guacamole deployment project:
mkdir guacamole-klutchcd guacamole-klutchgit initStep 2: Create the Dockerfile
Apache Guacamole consists of two main components: the Guacamole server (guacd) and the web application (guacamole-client). For simplicity, we’ll create a Dockerfile that sets up both components with an embedded database for quick starts, and provide production configuration options.
Create a Dockerfile in your project root directory:
FROM guacamole/guacamole:latest
# Environment variables for Guacamole configuration# These can be overridden in the Klutch.sh dashboardENV GUACD_HOSTNAME=localhostENV GUACD_PORT=4822
# PostgreSQL database configuration (recommended for production)# Uncomment and configure these in Klutch.sh environment variables# ENV POSTGRES_HOSTNAME=your-postgres-host# ENV POSTGRES_PORT=5432# ENV POSTGRES_DATABASE=guacamole_db# ENV POSTGRES_USER=guacamole_user# ENV POSTGRES_PASSWORD=secure_password
# MySQL database configuration (alternative to PostgreSQL)# ENV MYSQL_HOSTNAME=your-mysql-host# ENV MYSQL_PORT=3306# ENV MYSQL_DATABASE=guacamole_db# ENV MYSQL_USER=guacamole_user# ENV MYSQL_PASSWORD=secure_password
# Expose the default Guacamole web application portEXPOSE 8080Step 3: Create the Guacd Server Dockerfile
For production deployments, you’ll also need the Guacamole server daemon (guacd). Create a separate file named Dockerfile.guacd:
FROM guacamole/guacd:latest
# Expose the guacd port for Guacamole client connectionsEXPOSE 4822
# The guacd daemon will start automatically via the base image's entrypointNote: For a complete production setup, you would deploy both the guacd daemon and the Guacamole web application. For a simplified single-container deployment (suitable for testing or light usage), you can run Guacamole with guacd in the same network or use a multi-stage build.
Step 4: Create Database Initialization Script (PostgreSQL)
For production deployments, Guacamole requires a database. Create an initialization script named initdb.sql:
-- Create the Guacamole database schema-- This script should be run against your PostgreSQL database
CREATE TABLE guacamole_entity ( entity_id SERIAL NOT NULL, name VARCHAR(128) NOT NULL, type VARCHAR(16) NOT NULL, CONSTRAINT guacamole_entity_pk PRIMARY KEY (entity_id), CONSTRAINT guacamole_entity_name_type UNIQUE (name, type));
CREATE TABLE guacamole_user ( user_id SERIAL NOT NULL, entity_id INTEGER NOT NULL, password_hash BYTEA NOT NULL, password_salt BYTEA, password_date TIMESTAMP NOT NULL, disabled BOOLEAN NOT NULL DEFAULT FALSE, expired BOOLEAN NOT NULL DEFAULT FALSE, access_window_start TIME, access_window_end TIME, valid_from TIMESTAMP, valid_until TIMESTAMP, timezone VARCHAR(64), full_name VARCHAR(256), email_address VARCHAR(256), organization VARCHAR(256), organizational_role VARCHAR(256), CONSTRAINT guacamole_user_pk PRIMARY KEY (user_id), CONSTRAINT guacamole_user_entity FOREIGN KEY (entity_id) REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE);
-- Additional tables and schema...-- For the complete schema, download from:-- https://github.com/apache/guacamole-server/blob/master/doc/guacamole-auth-jdbc/postgres/schema/001-create-schema.sqlNote: The complete initialization script can be downloaded from the official Guacamole repository. For MySQL, use the corresponding MySQL schema files.
Step 5: Create Docker Compose for Local Testing
While Klutch.sh doesn’t support Docker Compose for deployment, you can use it for local development and testing. Create a docker-compose.yml:
version: '3.8'
services: guacd: image: guacamole/guacd:latest container_name: guacd restart: unless-stopped volumes: - guacd-data:/data
postgres: image: postgres:15 container_name: postgres-guacamole restart: unless-stopped environment: POSTGRES_USER: guacamole_user POSTGRES_PASSWORD: secure_password POSTGRES_DB: guacamole_db volumes: - postgres-data:/var/lib/postgresql/data - ./initdb.sql:/docker-entrypoint-initdb.d/initdb.sql
guacamole: image: guacamole/guacamole:latest container_name: guacamole restart: unless-stopped ports: - "8080:8080" environment: GUACD_HOSTNAME: guacd GUACD_PORT: 4822 POSTGRES_HOSTNAME: postgres POSTGRES_PORT: 5432 POSTGRES_DATABASE: guacamole_db POSTGRES_USER: guacamole_user POSTGRES_PASSWORD: secure_password depends_on: - guacd - postgres volumes: - guacamole-data:/data
volumes: guacd-data: postgres-data: guacamole-data:Step 6: Test Locally (Optional)
Before deploying to Klutch.sh, test your Guacamole setup locally:
# Start all servicesdocker-compose up -d
# Wait a moment for Guacamole to start, then access it# Open http://localhost:8080/guacamole in your browser
# Default credentials (change immediately after login):# Username: guacadmin# Password: guacadmin
# Stop and remove containers when donedocker-compose downImportant Security Note: The default credentials should be changed immediately after your first login. Navigate to Settings → Users → guacadmin and update the password.
Step 7: Push to GitHub
Commit your configuration files to your GitHub repository:
git add Dockerfile Dockerfile.guacd initdb.sql docker-compose.ymlgit commit -m "Add Guacamole Dockerfile and configuration"git remote add origin https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.gitgit push -u origin mainNote: Never commit sensitive credentials to your repository. Use environment variables for all passwords and sensitive configuration.
Database Setup
Apache Guacamole requires a database for production use. You have several options:
Option 1: PostgreSQL (Recommended)
PostgreSQL is the recommended database for Guacamole due to its reliability and feature set.
- Deploy a PostgreSQL database on Klutch.sh following the PostgreSQL deployment guide
- Download and run the official PostgreSQL schema script
- Configure the connection details in your Guacamole environment variables
Option 2: MySQL
MySQL is also fully supported and widely used with Guacamole.
- Deploy a MySQL database on Klutch.sh following the MySQL deployment guide
- Download and run the official MySQL schema script
- Configure the connection details in your Guacamole environment variables
Initializing the Database
Connect to your database and run the initialization script:
For PostgreSQL:
psql -h example-app.klutch.sh -p 8000 -U guacamole_user -d guacamole_db < 001-create-schema.sqlFor MySQL:
mysql -h example-app.klutch.sh -P 8000 -u guacamole_user -p guacamole_db < 001-create-schema.sqlEnvironment Variables
Configure these environment variables in the Klutch.sh dashboard:
Guacd Configuration
GUACD_HOSTNAME: The hostname or IP address of the guacd server (uselocalhostfor single-container setups)GUACD_PORT: The port guacd listens on (default:4822)
PostgreSQL Configuration
POSTGRES_HOSTNAME: PostgreSQL server hostnamePOSTGRES_PORT: PostgreSQL server port (default:5432)POSTGRES_DATABASE: Database name (e.g.,guacamole_db)POSTGRES_USER: Database usernamePOSTGRES_PASSWORD: Database password (use a strong, randomly generated password)
MySQL Configuration (Alternative)
MYSQL_HOSTNAME: MySQL server hostnameMYSQL_PORT: MySQL server port (default:3306)MYSQL_DATABASE: Database name (e.g.,guacamole_db)MYSQL_USER: Database usernameMYSQL_PASSWORD: Database password (use a strong, randomly generated password)
Optional LDAP/Active Directory Integration
LDAP_HOSTNAME: LDAP server hostnameLDAP_PORT: LDAP server port (default:389for LDAP,636for LDAPS)LDAP_USER_BASE_DN: Base DN for user searches (e.g.,ou=users,dc=example,dc=com)LDAP_CONFIG_BASE_DN: Base DN for Guacamole configurationLDAP_USERNAME_ATTRIBUTE: Attribute to use for usernames (default:uid)
Security and Session Configuration
GUACAMOLE_HOME: Directory for Guacamole configuration files (default:/guacamole)RECORDING_SEARCH_PATH: Path where session recordings are stored (requires persistent volume)
Security Best Practice: Always use strong, unique passwords and store them as environment variables in Klutch.sh. Never hardcode credentials in your Dockerfile or commit them to version control.
Deploying to Klutch.sh
Now that your Guacamole project is ready and pushed to GitHub, follow these steps to deploy it on Klutch.sh with persistent storage.
Deployment Steps
-
Log in to Klutch.sh
Navigate to klutch.sh/app and sign in to your account.
-
Create a New Project
Go to the dashboard and create a new project with a meaningful name (e.g., “Remote Desktop Gateway”).
-
Deploy the Guacd Daemon (Optional but Recommended for Production)
For production deployments, first deploy the guacd server daemon:
- Create a new app named “guacd”
- Select GitHub as your Git source
- Choose your repository and branch
- Ensure
Dockerfile.guacdis in the root directory, or create a separate repository with a standardDockerfilefor guacd - Traffic Type: Select TCP
- Internal Port: Set to
4822(the guacd daemon port) - Click “Create” to deploy
- Note the URL for the guacd service (e.g.,
guacd-app.klutch.sh)
-
Create the Guacamole Web Application
Navigate to create a new app and configure the following settings:
-
Select Your Repository
- Choose GitHub as your Git source
- Select the repository containing your Dockerfile
- Choose the branch you want to deploy (usually
mainormaster)
-
Configure Traffic Type
- Traffic Type: Select HTTP (Guacamole web interface is HTTP-based)
- Internal Port: Set to
8080(the default Guacamole web application port)
-
Set Environment Variables
Add the following environment variables for your Guacamole configuration:
For standalone deployment (simplified):
GUACD_HOSTNAME:localhostGUACD_PORT:4822
For production with separate guacd daemon:
GUACD_HOSTNAME: Your guacd app hostname (e.g.,guacd-app.klutch.sh)GUACD_PORT:8000(Klutch.sh routes TCP traffic through port 8000)
Database configuration (PostgreSQL example):
POSTGRES_HOSTNAME: Your PostgreSQL hostname (e.g.,postgres-app.klutch.sh)POSTGRES_PORT:8000(for Klutch.sh deployed databases)POSTGRES_DATABASE:guacamole_dbPOSTGRES_USER:guacamole_userPOSTGRES_PASSWORD: Your secure database password
Security Note: Always use strong, unique passwords for production deployments. Use a secure password generator.
-
Attach Persistent Volumes
Guacamole requires persistent storage for session recordings, configuration, and user data:
- In the Volumes section, click “Add Volume”
- Mount Path: Enter
/guacamole(for Guacamole configuration and home directory) - Size: Choose an appropriate size (e.g., 5GB for configuration, 50GB+ if storing session recordings)
If you plan to record sessions, add another volume:
- Mount Path: Enter
/recordings - Size: Allocate based on expected recording volume (e.g., 100GB+)
- Set
RECORDING_SEARCH_PATH=/recordingsin environment variables
Important: Persistent volumes ensure your Guacamole configuration, user data, and session recordings persist across deployments and restarts.
-
Configure Additional Settings
- Region: Select the region closest to your users for optimal latency
- Compute Resources: Choose appropriate CPU and memory (minimum 1GB RAM recommended, 2GB+ for production)
- Instances: Start with 1 instance (scale horizontally as needed for high availability)
-
Deploy Your Guacamole Instance
Click “Create” to start the deployment. Klutch.sh will:
- Automatically detect your Dockerfile in the repository root
- Build the Docker image with Guacamole
- Attach persistent volumes
- Start your Guacamole container
- Assign a URL for access
-
Access Your Guacamole Instance
Once deployment is complete, you’ll receive a URL like
example-app.klutch.sh. Navigate to:https://example-app.klutch.sh/guacamoleDefault Login Credentials (change immediately):
- Username:
guacadmin - Password:
guacadmin
- Username:
-
Change Default Credentials
After your first login:
- Click on your username (guacadmin) in the top-right corner
- Select Settings
- Go to Preferences → Change Password
- Set a strong, unique password
- Consider creating additional user accounts and disabling or removing the default guacadmin account for production
Configuring Remote Connections
Once Guacamole is running, you can configure connections to your remote systems.
Adding a New Connection
-
Navigate to Settings
Click on your username in the top-right corner and select Settings.
-
Access Connections
Click on the Connections tab.
-
Create New Connection
Click New Connection and configure the following:
-
Connection Details
- Name: A descriptive name for the connection (e.g., “Production Server”)
- Location: Organize connections into folders (optional)
- Protocol: Select the protocol (VNC, RDP, SSH, Kubernetes, or Telnet)
-
Protocol-Specific Settings
For RDP (Windows Remote Desktop):
- Hostname: IP address or hostname of the Windows server
- Port:
3389(default RDP port) - Username: Windows username
- Password: Windows password
- Domain: Windows domain (if applicable)
- Security mode: Any, NLA, TLS, or RDP
- Ignore server certificate: Enable if using self-signed certificates
For VNC (Linux/Unix Desktop):
- Hostname: IP address or hostname of the VNC server
- Port:
5901(or your VNC port, typically 5900 + display number) - Password: VNC password
- Color depth: Appropriate color depth for your use case
For SSH (Terminal Access):
- Hostname: IP address or hostname of the SSH server
- Port:
22(default SSH port) - Username: SSH username
- Password: SSH password (or use private key authentication)
- Private key: SSH private key content (for key-based authentication)
- Private key passphrase: If your key is password-protected
-
Display and Recording Settings
- Recording path: Set to
/recordingsif you configured persistent storage - Create recording automatically: Enable to record all sessions
- Screen recording name: Pattern for recording filenames
- Recording path: Set to
-
Save Configuration
Click Save to create the connection.
Connecting to Remote Systems
- Return to the Guacamole home screen
- Click on the connection you created
- The remote desktop or terminal will open in your browser
- Interact with the remote system as if you were physically at the machine
Production Best Practices
Security Recommendations
- Change Default Credentials: Immediately change the default
guacadminpassword after initial setup - Use Strong Passwords: Implement complex passwords for all user accounts and database connections
- Enable Two-Factor Authentication: Configure TOTP or RADIUS 2FA for enhanced security
- HTTPS Only: Ensure all connections to Guacamole use HTTPS (Klutch.sh provides this automatically)
- Disable Root Access: Create non-root users with appropriate permissions
- Regular Updates: Keep Guacamole, guacd, and database versions up to date with security patches
- Session Timeout: Configure automatic session timeout for inactive users
- Connection Permissions: Use Guacamole’s permission system to restrict connection access by user/group
- Audit Logging: Enable session recording for compliance and security auditing
- Network Isolation: Keep backend systems (databases, guacd) on private networks when possible
Performance Optimization
- Database Connection Pooling: Ensure your database is configured with appropriate connection pools
- Resource Allocation: Allocate sufficient CPU and RAM based on concurrent user count
- Minimum: 1 vCPU, 1GB RAM (up to 10 concurrent sessions)
- Recommended: 2 vCPUs, 2GB RAM (10-50 concurrent sessions)
- Production: 4+ vCPUs, 4GB+ RAM (50+ concurrent sessions)
- Horizontal Scaling: Deploy multiple Guacamole instances behind a load balancer for high availability
- Session Recording Optimization: Use efficient encoding settings to balance quality and storage
- Database Optimization: Index frequently queried tables and optimize database performance
- Guacd Placement: Deploy guacd on the same network as remote systems for lower latency
Backup Strategy
Implement a comprehensive backup strategy:
Backup the Database:
# PostgreSQLpg_dump -h example-app.klutch.sh -p 8000 -U guacamole_user guacamole_db > guacamole-backup.sql
# MySQLmysqldump -h example-app.klutch.sh -P 8000 -u guacamole_user -p guacamole_db > guacamole-backup.sqlBackup Persistent Volumes:
- Regularly backup the
/guacamoledirectory (configuration and user data) - Backup the
/recordingsdirectory (if using session recording) - Consider using automated backup solutions or object storage sync
Restore from Backup:
# PostgreSQLpsql -h example-app.klutch.sh -p 8000 -U guacamole_user guacamole_db < guacamole-backup.sql
# MySQLmysql -h example-app.klutch.sh -P 8000 -u guacamole_user -p guacamole_db < guacamole-backup.sqlConsider:
- Daily automated database backups
- Weekly configuration backups
- Multiple backup retention periods (daily, weekly, monthly)
- Offsite backup storage for disaster recovery
- Regular restore testing to verify backup integrity
Monitoring
Monitor your Guacamole deployment for:
- Active Sessions: Number of concurrent active sessions
- Connection Success Rate: Percentage of successful connection attempts
- Response Time: Latency between user actions and remote system responses
- Resource Utilization: CPU, memory, and disk I/O usage
- Database Performance: Query execution time and connection pool usage
- Session Recording Storage: Available disk space for recordings
- Error Logs: Monitor guacd and Guacamole application logs for errors
- User Activity: Track login attempts, failed authentications, and access patterns
- Network Throughput: Bandwidth usage for remote sessions
Troubleshooting
Cannot Access Guacamole Interface
- Verify the deployment completed successfully in the Klutch.sh dashboard
- Ensure you’re accessing the correct URL with the
/guacamolepath - Check that HTTP traffic is selected and internal port is set to
8080 - Review application logs in the Klutch.sh dashboard for startup errors
Cannot Connect to Remote Systems
- Verify Network Connectivity: Ensure Guacamole can reach the remote system’s IP/hostname
- Check Protocol and Port: Confirm the correct protocol (RDP/VNC/SSH) and port number
- Validate Credentials: Verify username and password are correct
- Firewall Rules: Ensure the remote system’s firewall allows connections from Guacamole
- VNC Issues: Check that the VNC server is running on the remote system (
vncserver -list) - RDP Issues: Verify Remote Desktop is enabled on Windows systems
- SSH Issues: Confirm SSH service is running (
systemctl status sshd)
Database Connection Errors
- Verify database environment variables are set correctly in Klutch.sh
- Confirm database initialization script was run successfully
- Check network connectivity from Guacamole to the database host
- Test database connection manually:
psql -h hostname -p 8000 -U username -d database - Review database logs for authentication or connection errors
- Ensure the database user has appropriate permissions
Guacd Connection Failed
- If using separate guacd deployment, verify it’s running and accessible
- Check
GUACD_HOSTNAMEandGUACD_PORTenvironment variables - Ensure port
8000is used when connecting to Klutch.sh deployed guacd instances - Review guacd logs for connection or protocol errors
- Verify guacd has necessary protocol support compiled in
Session Recording Not Working
- Confirm persistent volume is attached at
/recordings(or your configured path) - Verify
RECORDING_SEARCH_PATHenvironment variable is set - Check that the recording path has sufficient disk space
- Ensure the Guacamole user has write permissions to the recording directory
- Review connection configuration to confirm recording is enabled
Performance Issues
- High Latency: Check network latency between Guacamole and remote systems
- Slow Response: Increase CPU and memory allocation in Klutch.sh
- Connection Drops: Verify network stability and adjust timeout settings
- Low Frame Rate: Reduce color depth or resolution settings for VNC/RDP
- High CPU Usage: Consider horizontal scaling with multiple instances
- Database Slow: Optimize database queries and add appropriate indexes
Authentication Errors
- Verify default credentials were changed successfully
- Check that user accounts exist in the database
- For LDAP/AD integration, verify LDAP server connectivity and credentials
- Review authentication logs for specific error messages
- Ensure password meets complexity requirements (if configured)
Advanced Configuration
Configuring Two-Factor Authentication (TOTP)
Enable TOTP-based two-factor authentication:
-
Set the following environment variables:
TOTP_ENABLED=trueTOTP_ISSUER="Guacamole"TOTP_DIGITS=6TOTP_PERIOD=30 -
Users can enroll their TOTP devices from Settings → Preferences → Two-Factor Authentication
LDAP/Active Directory Integration
For enterprise deployments, integrate with LDAP or Active Directory:
# Add to your DockerfileENV LDAP_HOSTNAME=ldap.example.comENV LDAP_PORT=389ENV LDAP_USER_BASE_DN=ou=users,dc=example,dc=comENV LDAP_CONFIG_BASE_DN=ou=guacamole,dc=example,dc=comENV LDAP_USERNAME_ATTRIBUTE=uidENV LDAP_SEARCH_BIND_DN=cn=admin,dc=example,dc=comENV LDAP_SEARCH_BIND_PASSWORD=admin_passwordCustom Branding and Theming
Customize the Guacamole interface by mounting custom CSS and images:
- Create a custom theme directory with your branding assets
- Mount it as a volume:
/guacamole/extensions/branding - Add custom CSS, logos, and favicon files
- Restart the Guacamole container to apply changes
Session Recording Playback
Review recorded sessions:
- Navigate to Settings → Sessions
- Click on a recorded session to view details
- Click Play to watch the session recording in your browser
- Use playback controls to pause, rewind, or fast-forward
Getting Started Examples
Example 1: Connecting to a Ubuntu Desktop (VNC)
-
On your Ubuntu server, install and start a VNC server:
Terminal window sudo apt updatesudo apt install tightvncservervncserver :1 -geometry 1920x1080 -depth 24# Set a VNC password when prompted -
In Guacamole, create a new connection:
- Name: Ubuntu Desktop
- Protocol: VNC
- Hostname:
your-ubuntu-server-ip - Port:
5901(5900 + display :1) - Password: Your VNC password
- Color depth: True color (24-bit)
-
Connect and access your Ubuntu desktop through your browser
Example 2: Connecting to Windows Server (RDP)
-
On your Windows Server, ensure Remote Desktop is enabled:
- Open System Properties
- Navigate to Remote tab
- Select “Allow remote connections to this computer”
-
In Guacamole, create a new connection:
- Name: Windows Production Server
- Protocol: RDP
- Hostname:
your-windows-server-ip - Port:
3389 - Username: Your Windows username
- Password: Your Windows password
- Domain: Your Windows domain (if applicable)
- Security mode: Any
-
Connect and access your Windows desktop through your browser
Example 3: SSH Terminal Access
-
Ensure SSH is running on your server:
Terminal window sudo systemctl status sshd# Start if not running: sudo systemctl start sshd -
In Guacamole, create a new connection:
- Name: Production Server SSH
- Protocol: SSH
- Hostname:
your-server-ip - Port:
22 - Username: Your SSH username
- Password: Your SSH password (or use private key)
- Color scheme: Gray on black or your preference
-
Connect and access a full terminal session in your browser
Additional Resources
- Official Apache Guacamole Documentation
- Guacamole Docker Images
- Klutch.sh Documentation
- Klutch.sh Volumes Guide
- Guacamole Community Support
- Guacamole Client GitHub Repository
- Guacamole Server GitHub Repository
Conclusion
Deploying Apache Guacamole to Klutch.sh with Docker provides a powerful, browser-based remote desktop gateway solution that requires no client software. By following this guide, you’ve set up a production-ready Guacamole instance with persistent storage, database backend, and secure configuration. Whether you’re managing IT support operations, providing remote access to development environments, or enabling secure remote work, Guacamole on Klutch.sh offers a scalable and accessible solution for all your remote desktop needs.