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

LayerComponentRole
OSAlmaLinux 9Enterprise-grade, RHEL-compatible base; SELinux enforced security
RuntimeDocker EngineRuns Guacamole and supporting containers
ApplicationApache Guacamole (Web UI)HTML5 remote desktop gateway for RDP, VNC, SSH
Proxy Daemonguacd (in container)Translates RDP/VNC/SSH into browser-compatible streams
DatabasePostgreSQL/MySQL (optional)Stores users, roles, and connection configs for persistence
Reverse ProxyNginx (recommended)TLS termination, HTTP/2, authentication, access control
TLSLet’s Encrypt / PKIProvides 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/CapabilityApache GuacamoleVPN-only AccessProprietary Tools (AnyDesk, NoMachine)Native RDP/VNC Clients
Client requirementsNone (HTML5 browser)VPN clientProprietary softwareRDP/VNC client needed
Protocols supportedRDP, VNC, SSHNetwork tunneling onlyCustom/limitedRDP/VNC only
Multi-user managementYes (RBAC, DB backend)NoLimitedNo
SecurityTLS + RBAC + SELinuxVPN encryption onlyVendor-dependentBasic 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 and guacamole/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”.

Shape.host Resources dashboard with Create > Instance highlighted.

Select your preferred server location.

Shape.host instance form with the data center location selector highlighted.

Choose AlmaLinux 9 (64-bit) as the OS.

Pick a plan with at least 2 CPUs, 4 GB RAM, and 20 GB SSD.

Shape.host instance form with the operating system image selector highlighted.

Click “Create Instance”.

Shape.host instance form with the Create Instance button highlighted.

Copy your server IP address from the Resources section.

Shape.host Resources dashboard with the server IP address highlighted.

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
Terminal showing DNF/YUM package management commands and output.

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
Terminal showing DNF/YUM package management commands and output.

Enable and start Docker:

systemctl enable --now docker

Check installation:

docker --version
docker compose version
Terminal showing systemd service management commands or output.

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
Terminal showing hostname configuration or system identification details.

5. Initialize the PostgreSQL Database

Start database container:

docker compose up -d guacamole-db

Wait for DB to be ready:

sleep 10
Terminal showing container image download progress.

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
Terminal showing SQL database import commands.

Verify tables:

docker exec -it guac-db psql -U guacuser -d guacamole_db -c "\dt"
Terminal showing docker commands or output during Initialize the PostgreSQL Database.

6. Start Guacamole

Run containers:

docker compose up -d

Check status:

docker compose ps
Terminal showing container image download progress.

View logs:

docker logs guacamole --tail=100
Terminal showing docker commands or output during Start Guacamole.

Access Guacamole at:

http://your-server-ip:8080/guacamole

Default login:

  • Username: guacadmin
  • Password: guacadmin

👉 Change the admin password immediately after logging in.

Guacamole sign-in form.

7. Configure Nginx Reverse Proxy

Install Nginx:

dnf install nginx
Terminal showing DNF/YUM package management commands and output.

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
Terminal showing web server configuration text.

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
Terminal showing systemd service management commands or output.

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
Terminal showing systemd service management commands or output.

9. Enable SSL with Let’s Encrypt

Install Certbot:

dnf install epel-release
dnf install certbot python3-certbot-nginx
Terminal showing DNF/YUM package management commands and output.

Obtain SSL certificate:

certbot --nginx -d almalinux-tutorials.shape.host
Terminal showing Certbot certificate commands and messages.

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.

Guacamole sign-in form.
Guacamole connection list showing no recent connections.

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