
Secure Remote Access: Your Step-by-Step Guide to Installing Guacamole with Docker on Ubuntu
In today’s connected world, managing remote access to servers, desktops, and virtual machines is a critical task for IT professionals and home lab enthusiasts alike. Juggling multiple clients for RDP, VNC, and SSH can be cumbersome and inefficient. Apache Guacamole solves this problem by providing a centralized, clientless remote desktop gateway, accessible from any modern web browser.
By leveraging Docker, we can simplify the installation process, making it faster, more reliable, and easier to manage. This guide will walk you through deploying a robust Apache Guacamole stack on an Ubuntu server using Docker Compose.
Why Use Docker for Guacamole?
Deploying applications with Docker offers several key advantages:
- Isolation: Each component of the Guacamole stack (the web app, the daemon, and the database) runs in its own isolated container, preventing conflicts with other software on your host system.
- Simplicity: Docker Compose allows you to define and manage the entire multi-container application with a single configuration file.
- Portability: Your entire Guacamole setup can be easily moved to another Docker-enabled host with minimal effort.
- Scalability: While not covered in this guide, containerization makes it easier to scale components as your needs grow.
Prerequisites
Before we begin, ensure you have the following ready:
- An Ubuntu server (20.04 or newer is recommended).
- Docker and Docker Compose installed on your server.
- Basic familiarity with the Linux command line.
- A user account with
sudo
privileges.
Step 1: Prepare the Project Directory and Database Script
First, we’ll create a dedicated directory to hold our configuration files. This keeps our project organized and self-contained.
mkdir guacamole-docker
cd guacamole-docker
Next, Guacamole requires a database to store user and connection data. We will use MySQL (or MariaDB) running in a Docker container. To initialize this database properly, we need a setup script. Create a file named initdb.sql
inside a new init
directory.
mkdir init
nano init/initdb.sql
Paste the following SQL script into the file. This script creates the necessary database and user for Guacamole. Be sure to replace 'YOUR_STRONG_PASSWORD'
with a secure password of your own.
/*
* Create the database and user for Guacamole
*/
CREATE DATABASE guacamole_db;
CREATE USER 'guac_user'@'%' IDENTIFIED BY 'YOUR_STRONG_PASSWORD';
GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guac_user'@'%';
FLUSH PRIVILEGES;
/*
* Use the newly created database
*/
USE guacamole_db;
/*
* Create the core tables for Guacamole
*/
CREATE TABLE guacamole_user (
user_id int(11) NOT NULL AUTO_INCREMENT,
username varchar(128) NOT NULL,
password_hash binary(32) NOT NULL,
password_salt binary(32),
disabled boolean NOT NULL DEFAULT 0,
PRIMARY KEY (user_id),
UNIQUE KEY username (username)
);
-- (The rest of the default Guacamole schema tables follow)
-- NOTE: The official Guacamole Docker image will automatically
-- run the necessary schema scripts from /opt/guacamole/etc/schema
-- against the database defined. The above manual creation is
-- for clarity and to ensure the user and database exist with
-- correct permissions before the container starts.
Note: The official Guacamole authentication extension will automatically create the required tables if they don’t exist. This script primarily ensures the database and user are created with the correct permissions from the start.
Step 2: Create the Docker Compose File
This is the core of our setup. The docker-compose.yml
file defines all the services, networks, and volumes needed to run the entire Guacamole stack.
Create the file in your guacamole-docker
directory:
nano docker-compose.yml
Paste the following configuration into the file. Carefully review and replace the placeholder values (especially YOUR_STRONG_PASSWORD
and MYSQL_ROOT_PASSWORD
) with your own secure credentials.
version: '3.8'
services:
guacd:
image: guacamole/guacd
container_name: guacd
restart: unless-stopped
volumes:
- ./drive:/drive:rw
- ./record:/record:rw
networks:
- guacamole-net
mysql-db:
image: mysql:8.0
container_name: mysql-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'YOUR_SECURE_ROOT_PASSWORD'
MYSQL_DATABASE: 'guacamole_db'
MYSQL_USER: 'guac_user'
MYSQL_PASSWORD: 'YOUR_STRONG_PASSWORD'
volumes:
- ./mysql-data:/var/lib/mysql
- ./init:/docker-entrypoint-initdb.d
networks:
- guacamole-net
guacamole:
image: guacamole/guacamole
container_name: guacamole
restart: unless-stopped
depends_on:
- guacd
- mysql-db
environment:
GUACD_HOSTNAME: guacd
MYSQL_HOSTNAME: mysql-db
MYSQL_DATABASE: guacamole_db
MYSQL_USER: guac_user
MYSQL_PASSWORD: 'YOUR_STRONG_PASSWORD'
ports:
- "8080:8080"
networks:
- guacamole-net
networks:
guacamole-net:
driver: bridge
Let’s break down what this file does:
- guacd: This is the Guacamole proxy daemon. It’s the core component that translates browser commands into native remote desktop protocols like RDP, SSH, and VNC.
- mysql-db: This service runs a MySQL database to store all your configuration data, including users, passwords, and connection details. The
volumes
section ensures that your data persists even if the container is removed. - guacamole: This is the main web application that you interact with in your browser. It depends on
guacd
andmysql-db
to function. We expose port8080
to access the web interface. - networks: We create a dedicated bridge network called
guacamole-net
to allow the containers to communicate with each other securely by name.
Step 3: Launch and Access Guacamole
With the configuration files in place, launching the stack is as simple as running one command from your guacamole-docker
directory:
sudo docker-compose up -d
Docker will now pull the required images and start the containers in the background (-d
for detached mode). You can check the status of your containers with:
sudo docker-compose ps
Once all services show a status of “Up” or “healthy,” you can access the Guacamole web interface by navigating to http://your_server_ip:8080/guacamole
.
The default administrator login credentials are:
- Username: guacadmin
- Password: guacadmin
Actionable Security Tip: Your very first action should be to log in and immediately change the default administrator password. Navigate to Settings > Users, select the guacadmin
user, and set a new, strong password.
Step 4: Secure Your Installation with a Reverse Proxy and SSL
Exposing Guacamole directly on port 8080 is not recommended for production use. For enhanced security, you should place it behind a reverse proxy like Nginx and secure it with an SSL certificate.
This provides two major benefits:
- SSL/TLS Encryption: All traffic between your browser and the server will be encrypted, protecting your credentials and session data.
- Clean URL: You can access Guacamole via a standard domain name (e.g.,
https://remote.yourdomain.com
) without needing to specify a port number.
Assuming you have Nginx installed and a domain name pointed to your server’s IP, create a new Nginx configuration file:
sudo nano /etc/nginx/sites-available/guacamole
Paste in the following configuration, replacing remote.yourdomain.com
with your actual domain name.
server {
listen 80;
server_name remote.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name remote.yourdomain.com;
# SSL configuration (adjust paths for your certificate)
ssl_certificate /etc/letsencrypt/live/remote.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/remote.yourdomain.com/privkey.pem;
access_log /var/log/nginx/guacamole.access.log;
error_log /var/log/nginx/guacamole.error.log;
location /guacamole/ {
proxy_pass http://localhost:8080/guacamole/;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_cookie_path /guacamole/ /;
}
}
Enable the site and use Certbot to obtain a free Let’s Encrypt SSL certificate.
# Enable the new site configuration
sudo ln -s /etc/nginx/sites-available/guacamole /etc/nginx/sites-enabled/
# Test Nginx configuration
sudo nginx -t
# Obtain SSL certificate and restart Nginx
sudo certbot --nginx
You can now securely access your Guacamole instance at https://remote.yourdomain.com/guacamole/
. You have successfully deployed a powerful, secure, and self-hosted remote access gateway.
Source: https://kifarunix.com/install-apache-guacamole-as-docker-container-on-ubuntu/