Skip to content

Guacamole with MySQL on Ubuntu (Docker Version)

Many of you have used my previous scripts for installing Guacamole directly, this is an updated version which uses Docker to greatly simplify the process! All you have to do is type two passwords, the MySQL ROOT Password and the Guacamole database user password. Run as root!



# Version number of Guacamole to install

# Get script arguments for non-interactive mode
while [ "$1" != "" ]; do
    case $1 in
        -m | --mysqlpwd )
        -g | --guacpwd )

# Get MySQL root password and Guacamole User password
if [ -n "$mysqlpwd" ] && [ -n "$guacpwd" ]; then
    while true
        read -s -p "Enter a MySQL ROOT Password: " mysqlrootpassword
        read -s -p "Confirm MySQL ROOT Password: " password2
        [ "$mysqlrootpassword" = "$password2" ] && break
        echo "Passwords don't match. Please try again."
    while true
        read -s -p "Enter a Guacamole User Database Password: " guacdbuserpassword
        read -s -p "Confirm Guacamole User Database Password: " password2
        [ "$guacdbuserpassword" = "$password2" ] && break
        echo "Passwords don't match. Please try again."

#Install Stuff
apt-get update
apt-get -y install mysql-client wget

# Set SERVER to be the preferred download server from the Apache CDN

# Download Guacamole authentication extensions
wget -O guacamole-auth-jdbc-${GUACVERSION}.tar.gz ${SERVER}/binary/guacamole-auth-jdbc-${GUACVERSION}.tar.gz
if [ $? -ne 0 ]; then
    echo "Failed to download guacamole-auth-jdbc-${GUACVERSION}.tar.gz"
    echo "${SERVER}/binary/guacamole-auth-jdbc-${GUACVERSION}.tar.gz"

tar -xzf guacamole-auth-jdbc-${GUACVERSION}.tar.gz

# Start MySQL
docker run --restart=always --detach --name=mysql --env="MYSQL_ROOT_PASSWORD=$mysqlrootpassword" --publish 3306:3306 mysql

# Sleep to let MySQL load (there's probably a better way to do this)
echo "Waiting 30 seconds for MySQL to load"
sleep 30

# Create the Guacamole database and the user account
# SQL Code
create database guacamole_db; 
create user 'guacamole_user'@'%' identified by '$guacdbuserpassword'; 
GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'%'; 
flush privileges;"

# Execute SQL Code
echo $SQLCODE | mysql -h -P 3306 -u root -p$mysqlrootpassword

cat guacamole-auth-jdbc-${GUACVERSION}/mysql/schema/*.sql | mysql -u root -p$mysqlrootpassword -h -P 3306 guacamole_db

docker run --restart=always --name guacd -d guacamole/guacd
docker run --restart=always --name guacamole  --link mysql:mysql --link guacd:guacd -e MYSQL_HOSTNAME= -e MYSQL_DATABASE=guacamole_db -e MYSQL_USER=guacamole_user -e MYSQL_PASSWORD=$guacdbuserpassword --detach -p 8080:8080 guacamole/guacamole

rm -rf guacamole-auth-jdbc-${GUACVERSION}*

As usual, connect via :8080/guacamole/ and login with guacadmin/guacadmin to begin configuration. Please make sure to change the guacadmin password…

Published inTech


  1. JP JP

    Awesome writeup… thanks. I get an error on install and it doesn’t finish, any ideas?

    mysql: [Warning] Using a password on the command line interface can be insecure.
    ERROR 2013 (HY000): Lost connection to MySQL server at ‘reading initial communication packet’, system error: 2
    mysql: [Warning] Using a password on the command line interface can be insecure.
    ERROR 2013 (HY000): Lost connection to MySQL server at ‘reading initial communication packet’, system error: 2

    • Chase Chase

      My first guess is bad MySQL password. There’s no space after The -p and I’m not sure how well special characters are handled

      • JP JP

        So should this line

        read -s -p “Enter the password that will be used for MySQL Root: ” MYSQLROOTPAS$

        actually be
        read -s -p”Enter the password that will be used for MySQL Root: ” MYSQLROOTPAS$

        notice the lack of space between the -p and the first ”

        Or, did I totally misunderstand the script and I should actually be putting something in the script? I am fine with putting my password in the script. My password is alphanumeric only, no special characters.

        Thanks for the reply!

        • Chase Chase

          I’m referring to lines 18 and 20 where you’re passing the password to MySQL in “-u root -p$MYSQLROOTPASSWORD”

      • Sam Sam

        Hi Chase,

        I am trying to run it on Centos using yum and it is fail, is there any differences that I may miss



  2. JP JP

    I see, that makes sense. Well it must be in my environment, I can confirm mysql is running, but mysql-client cannot connect to it. I realize I am running xubuntu rather than ubuntu, same version though, I assumed it would work but there must be something holding me back.

    Great writeup nonetheless, and if I get some time to play with an actual ubuntu machine again I will give it another shot. I am trying to standardize a setup for a lightweight box with a gui to put in client sites as an rdp gateway and also a jumpbox for other maintenance tasks, and having a gui makes it easier for someone filling in to at least verify connectivity and simple stuff like that if I can’t get to it remotely.

  3. Oliver Oliver


    Looks promising but does not run on Ubuntu 16.04.1 LTS

    Installation works fine. I get the same error messages as JP did but that seems not to be the problem. I executed statement by statement and checked the MYSQL DB. The tables get created. Even the docker images are running and port 8080 is accessible.

    When accessing the URL: http://guacamole:8080/guacamole (my systems name is guacamole) I see the icon in chromes/IEs tab.

    BUT the page stays empty. No login dialog 🙁

    If I look at the page source I can see some guac specific stuff loaded.

    Any idea why this is not working ?

    BTW, the old style installation (your other post) works fine. But I thought that docker would be cooler. It’s not so fa.


    • Chase Chase

      Can you try this?

      echo "create database guacamole_db; create user 'guacamole_user'@'%' identified by "$GUACDBUSERPASSWORD";GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'%';flush privileges;" | mysql -h -P 3306 -u root -p$MYSQLROOTPASSWORD

      Notice the % after the @ instead of localhost? Does that fix it?

      • Oliver Oliver

        Hi Chase

        That did the trick. It works now !

        Now I have a different problem. I defined a RDP Connection and tried to launch it. The target system refused it and guacamole did log me out. Now always when I login it tries to reestablish the connection and counts down from 15 seconds to 0. The only option I have is “Reconnect” or “Logout”.

        So basically the system locked me out. It doesn’t matter which login I use (guacadmin or my created user) it always want’s to establish this broken connection 🙁

        Any idea how to fix this?

        Additional question:

        Would this exact setup instructions work on a Fedora 24 box as well ?


        • Jason Miller Jason Miller

          When it’s trying to reconnect hit “Ctrl+Alt+Shift” which brings up the menu on the left. From there you can go to the “Settings” page. When you only have 1 connection, Guacamole will always try to automatically log you into that one. Just create another bogus entry so that it doesn’t do that anymore.

  4. Oliver Oliver

    You should add a

    sleep 15


    # Start MySQL
    docker run –restart=always –detach –name=mysql –env=”MYSQL_ROOT_PASSWORD=$MYSQLROOTPASSWORD” –publish 3306:3306 mysql
    sleep 15

    Because if you script your statements into a file and run it using bash the mysql container is not yet up when you try to create the database.


    • Chase Chase

      I updated the script with a while loop to check for the successful login and interaction with MySQL, it’ll sleep until MySQL is ready to receive the commands to create the database.

  5. daniel daniel

    If someone can figure the setups for https and TwoFactorAuth (ala google authenticator) then this would be perfect. With or without docker version.

  6. jear71 jear71

    Hi ,

    Great integration job indeed. I tested the script 1 or 2 weeks ago and it was working perfectly.
    I decided to use it again this week.

    When I log in with guacadmin/guacadmin, I only see a ‘logout’ in the top-left menu.
    When I open my brower console (firefox on ubuntu and Chrome on Windows), I get 403 and then a 500 errors.

    http://guacamole:8080/guacamole/api/session/data/mysql/self/permissions [HTTP/1.1 500 Internal Server Error 27ms]

    POST [HTTP/1.1 403 Forbidden 9ms]

    I noticed that the version is 0.9.10 and not 0.9.9….

    Any idea?

  7. I ran the script on a fairly fresh install of Linux Mint. At first I thought everything went great but when I logged on to localhost:8080/guacamole/ using the default username/password, things didn’t seem right. Looking at ‘ docker logs guacamole ‘, it appears there is no “guacamole_db.guacamole_sharing_profile_permission” table. I will investigate further (I just found about guacamole last week) but I was wondering whether you or anyone else had any clues as to what could be causing this?
    Links to log:
    And screenshot of what the browser interface looks like

  8. Nice post!

    For those looking for 2FA and SSL, deploy a KEMP VLB in front of your guacamole with ESP enabled and SSL offload.

    Details at

  9. Scott Scott

    Ran the script and the install was clean. Was able to get in, setup accounts, etc. Great! Then when I restarted Ubuntu, I was unable to get back in.

    Checked if the services (i.e. tomcat) were up and nothing was up. I tried to startup the services and got this:

    ……# /etc/init.d/guacd start
    -bash: /etc/init.d/guacd: No such file or directory

    So I did some poking around on the folders others have listed for relevant file locations (i.e. for tomcat, guacamole, etc.) and I have none of the folders. I then did a find to locate the associated files and everything shows up in crazy paths like:


    I’m running 16.10. Any suggestions?


  10. I tried getting this working because this seemed like it would teach me a few things (docker for the most part). It all worked extremely well. I can log in with the default user, change the password, create connections, etc.

    But … I went to create a new user and it fails with a dialog saying “Unexpected Server Error”

    I ran a “docker logs guacamole” and there’s this in the logs:

    03:36:55.550 [http-nio-8080-exec-2] ERROR – Unexpected internal error:
    ### Error updating database. Cause: java.sql.SQLException: Field ‘password_date’ doesn’t have a default value
    ### The error may involve org.apache.guacamole.auth.jdbc.user.UserMapper.insert-Inline
    ### The error occurred while setting parameters
    ### SQL: INSERT INTO guacamole_user ( username, password_hash, password_salt, disabled, expired, access_window_start, access_window_end, valid_from, valid_until, timezone ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
    ### Cause: java.sql.SQLException: Field ‘password_date’ doesn’t have a default value
    13-Feb-2017 03:36:55.551 SEVERE [http-nio-8080-exec-2] null.null Mapped exception to response: 500 (Internal Server Error)

    Any help?

    BTW – running a new vm that I have “apt update; apt upgrade” to the latest. It reports itself as “Ubuntu 16.04.2 LTS”


    root@guac:~# docker images
    mysql latest 7666f75adb6b 2 weeks ago 405.6 MB
    glyptodon/guacd latest 34d5d942af2e 3 weeks ago 329.8 MB
    glyptodon/guacamole latest 1b557c527e87 3 weeks ago 650.2 MB

    • Chase Chase

      It sounds like there might be an issue with the new password requirement options…? You ran everything for 0.9.11? Or did you do this when it was still 0.9.10?

      • This was a brand new environment and ran the script that’s posted right now. In other words a clean install assuming that it would get 0.9.11

        • Chase Chase

          So it looks like with 0.9.11 they switch from glyptodon to guacamole…I didn’t notice that in the manual so the script has been updated…it’s now guacamole/guacd and guacamole/guacamole..sorry about that. I run the native version myself.

          • awesome! Thanks so much. I blew away all the docker images and re-ran the updated script. All’s working now.

            Appreciate the quick help Chase.

  11. Pablo Ramos Pablo Ramos

    Hi Chase! Great tutorial/script. I’m already running Guacamole installed by manual instructions from apache website, and it’s a wonderful tool. By the way, I’m accessing Guacamole from my phone, but on trying to show the client menu (swiping my finger on screen to right from the left border), I can not make it appear. Do you have notice about problems like that? Thanks for your help.

  12. Chase –

    FWIW 0.9.12 is out and it took a bit for me to figure out the right(?) way to upgrade the docker images. I did double check to make sure there was no schema changes (downloaded the schema .sql files by hand). After that I ran the following commands:

    docker pull guacamole/guacd
    docker pull guacamole/guacamole
    docker rm -f guacamole
    docker rm -f guacd
    docker run –restart=always –name guacd -d guacamole/guacd
    docker run –restart=always –name guacamole –link mysql:mysql –link guacd:guacd -e MYSQL_HOSTNAME= -e MYSQL_DATABASE=guacamole_db -e MYSQL_USER=guacamole_user -e MYSQL_PASSWORD=PASSWORD –detach -p 8080:8080 guacamole/guacamole

    Also, I noticed that the script as posted is still referencing glyptodon instead of guacamole. I think you might have had a regression on that

  13. Alex Hansen Alex Hansen

    Thanks for your efforts! I had already set up an Ubuntu VM with guacamole/guacd using your “standard” script, so I thought I’d try an adaptation of this script to install Docker versions of guacamole, guacd, and mysql on my Mac. This worked, with the following notes:
    1) Download and install Docker for Mac via its installer package.
    2) curl is a system built-in on macOS/OS X , but folks would need to get the other executables (mysql, wget, jq) by other means.
    3) I had to make ‘$guacdbuserpassword’ upper-case in SQLCODE .
    4) the mysql commands timed out for me with “ERROR 2013 (HY000): Lost connection to MySQL server at ‘reading authorization packet’, system error: 0” when run in the script, but manually running the commands worked for me.

    • Chase Chase

      Thanks, I corrected the GUACDBUSERPASSWORD issue and re-arranged the curl and jq apt-get installs on the website

  14. Hi Chase,

    Thank you very much for opening your script. Everything went well until the first reboot. Any ideia what it could be ?


  15. Jan Zarstek Jan Zarstek

    After the start of the mysql-container the script has to wait a moment for mysql to initialize.
    On my machine it was too fast, so that the database and user were not created, because mysql was not ready to recieve commands.

  16. Greg Greg

    Is it possible to force Tomcat7 with the Docker script? When I run the script on a fresh install, guacamole starts up and works fine. But it doesn’t work following a system reboot. Wondering whether that’s a Tomcat8 issue.

  17. Vamp Vamp

    It is great, but what will happen, if i update mysql docker?

    Now i create the system , and it is working well, but now check it, that inside the script not configured a custom volume to the data.

    So if i pull a new myql image what is the correct method to migrate the existing datas? (database, connection methods, etc…)

    The other two container i think not store any data (only if i want to extra config )

  18. Vamp Vamp

    I update your install script to install latest Guacamole.

    I do some changes:

    1. Replace auth module path, the variable method not working for me. Now it use a static website address.

    2. Add “Sleep 40” command, after run mysql docker. It add some time to the system to start container propertly.

    3. Add a custom config possibility . Now it easy to add two factor authentication (Duo Security) or some other stuffs.

    Note: It not a update script, it only working if you want a fresh install!!!

    • Vamp Vamp

      I deleted “stuff” installation line. If you want to install it, add this line to begin of script:

      #Install Stuff
      apt-get update
      apt-get install mysql-client wget jq curl

  19. Jay Jay

    Hi, I really appreciate the time you put into this. Runs great.
    Is there a way for me (I’m noobish) to get this to run everything on port 80 instead of 8080?
    Advice is greatly appreciated IF YOUR WILLING.


  20. XrX XrX

    A suggestion for determining when the mysql server is ready (I was working on a similar script when I saw yours)

    until docker logs mysql 2>&1 | grep -q “port: 3306”; do sleep 0.5; done

    Again maybe not the best way, but I’ve been using it on a couple docker setup scripts that need mysql servers and it’s been working.

  21. Frank Frank

    When trying this script with Debian 9 I have had some problems:
    – Debian 9 does not have to install. I have installed docker-ce following the official documentation. As the apt-get install fails, it is neccesary to manually install also mysql-client
    – Running mysql image without arguments gets version 8, and it gives authentication problems when running the SQL Code:

    My solution is to run mysql:5 in the script instead of mysql:latest. Not really a solution, just a workaround.

Leave a Reply

Your email address will not be published. Required fields are marked *