Apache Guacamole (Docker) on AlmaLinux 9 (Nginx + SSL)
Apache Guacamole is a clientless remote desktop gateway that supports RDP, VNC, and SSH — all accessible through a standard web browser. Since it’s based on HTML5, there’s no need for plugins or local clients: once deployed, Guacamole lets users securely connect to desktops and servers from anywhere with nothing but a browser.
Running Guacamole in Docker makes deployment simple: the Guacamole web application, the guacd
proxy daemon, and the optional database backend are containerized for portability and easy upgrades. With AlmaLinux 9, a stable, RHEL-compatible enterprise OS, you get a hardened, long-term supported foundation that’s trusted in production environments — perfect for secure remote access infrastructure.
Architecture Overview
Layer | Component | Role |
---|---|---|
OS | AlmaLinux 9 | Enterprise-grade, RHEL-compatible base; SELinux enforced security |
Runtime | Docker Engine | Runs Guacamole and supporting containers |
Application | Apache Guacamole (Web UI) | HTML5 remote desktop gateway for RDP, VNC, SSH |
Proxy Daemon | guacd (in container) | Translates RDP/VNC/SSH into browser-compatible streams |
Database | PostgreSQL/MySQL (optional) | Stores users, roles, and connection configs for persistence |
Reverse Proxy | Nginx (recommended) | TLS termination, HTTP/2, authentication, access control |
TLS | Let’s Encrypt / PKI | Provides HTTPS for secure browser-based access |
Why Use Apache Guacamole?
- Clientless access – everything works in the browser; no plugins required.
- Multi-protocol support – manage RDP, VNC, and SSH from a single interface.
- Centralized access – unified portal for multiple systems and users.
- Secure and enterprise-ready – TLS encryption, SELinux enforcement, RBAC, and optional MFA/SSO.
- Containerized deployment – lightweight, portable, and easy to maintain.
Guacamole vs Other Remote Access Solutions
Feature/Capability | Apache Guacamole | VPN-only Access | Proprietary Tools (AnyDesk, NoMachine) | Native RDP/VNC Clients |
---|---|---|---|---|
Client requirements | None (HTML5 browser) | VPN client | Proprietary software | RDP/VNC client needed |
Protocols supported | RDP, VNC, SSH | Network tunneling only | Custom/limited | RDP/VNC only |
Multi-user management | Yes (RBAC, DB backend) | No | Limited | No |
Security | TLS + RBAC + SELinux | VPN encryption only | Vendor-dependent | Basic encryption |
Guacamole is strongest when you need secure, browser-based access for multiple protocols without requiring extra client software.
Security & Best Practices
- Deploy Guacamole behind Nginx with SSL.
- Use Let’s Encrypt or enterprise PKI for TLS certificates.
- Limit exposure with firewall rules and SELinux policies.
- Store user accounts and permissions in PostgreSQL or MySQL for persistence.
- Enable MFA or SSO for enterprise-grade authentication.
- Keep Docker images (
guacamole/guacd
andguacamole/guacamole
) regularly updated. - Add Fail2Ban/rate limiting on Nginx to protect against brute-force attempts.
Typical Use Cases
- Secure remote desktop gateway for IT teams.
- Centralized SSH access to Linux servers.
- Web-based access to Windows desktops and RDP servers.
- Lightweight alternative to full VPN-based access.
- BYOD (Bring Your Own Device) environments where users only need a browser.
1. Create a Shape.Host VPS Instance
Go to https://shape.host and log in.
Click “Create” → “Instance”.

Select your preferred server location.

Choose AlmaLinux 9 (64-bit) as the OS.
Pick a plan with at least 2 CPUs, 4 GB RAM, and 20 GB SSD.

Click “Create Instance”.

Copy your server IP address from the Resources section.

2. Connect to Your VPS
On Linux/macOS
ssh root@your-server-ip
On Windows
- On Windows 10/11 PowerShell:
ssh root@your-server-ip
- On older Windows, download PuTTY and connect with your server’s IP as root.
3. Update System and Install Docker
Update system packages:
dnf update

Add Docker repo:
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
Install Docker and plugins:
dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Enable and start Docker:
systemctl enable --now docker
Check installation:
docker --version
docker compose version

4. Set Up Apache Guacamole with Docker Compose
Create working directory:
mkdir -p /opt/guacamole
cd /opt/guacamole
Create docker-compose.yml
:
cat > docker-compose.yml <<'YML'
services:
guacamole-db:
image: postgres:15
container_name: guac-db
environment:
POSTGRES_USER: guacuser
POSTGRES_PASSWORD: StrongPassword123!
POSTGRES_DB: guacamole_db
volumes:
- db_data:/var/lib/postgresql/data
restart: unless-stopped
guacd:
image: guacamole/guacd:1.5.5
container_name: guacd
restart: unless-stopped
guacamole:
image: guacamole/guacamole:1.5.5
container_name: guacamole
environment:
POSTGRES_HOSTNAME: guacamole-db
POSTGRES_DATABASE: guacamole_db
POSTGRES_USER: guacuser
POSTGRES_PASSWORD: StrongPassword123!
GUACD_HOSTNAME: guacd
GUACD_PORT: 4822
ports:
- "8080:8080"
depends_on:
- guacamole-db
- guacd
restart: unless-stopped
volumes:
db_data:
YML

5. Initialize the PostgreSQL Database
Start database container:
docker compose up -d guacamole-db
Wait for DB to be ready:
sleep 10

Generate schema:
docker run --rm guacamole/guacamole:1.5.5 /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql
Import schema into database:
docker exec -i guac-db psql -U guacuser -d guacamole_db < initdb.sql

Verify tables:
docker exec -it guac-db psql -U guacuser -d guacamole_db -c "\dt"

6. Start Guacamole
Run containers:
docker compose up -d
Check status:
docker compose ps

View logs:
docker logs guacamole --tail=100

Access Guacamole at:
http://your-server-ip:8080/guacamole
Default login:
- Username:
guacadmin
- Password:
guacadmin
👉 Change the admin password immediately after logging in.

7. Configure Nginx Reverse Proxy
Install Nginx:
dnf install nginx

Enable and start Nginx:
systemctl enable --now nginx
Create Nginx config:
cat > /etc/nginx/conf.d/guacamole.conf <<'NGINX'
server {
listen 80;
server_name almalinux-tutorials.shape.host;
location / {
proxy_pass http://127.0.0.1:8080/guacamole/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSockets (required for RDP/VNC)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
}
NGINX

Fix long server names:
printf "server_names_hash_bucket_size 128;\n" > /etc/nginx/conf.d/hash_bucket.conf
Reload Nginx:
nginx -t && systemctl reload nginx

8. Configure SELinux and Firewall
Allow Nginx to connect externally:
setsebool -P httpd_can_network_connect 1
Enable FirewallD:
systemctl unmask firewalld
systemctl enable --now firewalld
Allow web traffic:
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload

9. Enable SSL with Let’s Encrypt
Install Certbot:
dnf install epel-release
dnf install certbot python3-certbot-nginx

Obtain SSL certificate:
certbot --nginx -d almalinux-tutorials.shape.host

10. Access Guacamole
Now open your browser and visit:
https://almalinux-tutorials.shape.host
Log in with the default credentials and change the password immediately.


This tutorial was tested on a Shape.Host Cloud VPS.
With Shape.Host, you get:
- High-performance VPS in multiple global locations
- Support for Ubuntu, Debian, AlmaLinux, and Rocky Linux
- Instant scaling of CPU, RAM, and storage
- Built-in backups, snapshots, and monitoring
Start now at https://shape.host and deploy Apache Guacamole in minutes