Umami is an open-source, self-hosted web analytics application written in Node.js. It focuses on being simple, well-designed, fast, and privacy-focused. It can store data about your website’s visitors in either a MySQL or PostgreSQL database.
In this tutorial you will install Umami and a PostgreSQL database using Docker Compose, then install Nginx to act as a reverse proxy for Umami. Finally, you will enable secure HTTPS connections by using Certbot to download and configure SSL certificates from the Let’s Encrypt Certificate Authority.
In order to complete this tutorial, you’ll first need the following:
docker
commands without using sudo
Note: These prerequisite steps can be skipped if you’re using DigitalOcean’s 1-Click Docker Image. This image will have Docker, Docker Compose, and UFW already installed and configured.
Launch a new Docker image in the region of your choice, then log in as the root user and proceed with the tutorial. Optionally, you could leave off the sudo
parts of all commands, but it’s not necessary.
Finally, to enable SSL you’ll need a domain name pointed at your server’s public IP address. This should be something like example.com
or umami.example.com
, for instance. If you’re using DigitalOcean, please see our DNS Quickstart for information on creating domain resources in our control panel.
When you’ve satisfied all the prerequisites, proceed to Step 1, where you’ll download and launch the Umami software.
Your first step will be to clone the Umami Git repository, update the docker-compose.yml
configuration file, and then start the Umami and PostgreSQL containers.
You’ll download the repo into the /opt
directory. Use the cd
command to go there now:
- cd /opt
Then use the git
command to clone the repo from GitHub:
- sudo git clone https://github.com/mikecao/umami.git
This will pull all the software and configuration files into /opt/umami
. Move into the newly created umami
directory now:
- cd umami
Now you need to update the project’s docker-compose.yml
file. This file is what the docker-compose
command uses to configure and launch multiple Docker containers at once. We need to change two options in this file: the IP that Umami binds to, and a random hash used as a salt when encrypting things in the database.
Before you open docker-compose.yml
to edit it, let’s generate a new random hash to paste into the file:
- openssl rand -base64 32
OutputtCgKyCWc/3C9VH+Ex0TysXsGEKQklQXm0H3nSnlR48g=
This uses the openssl
command to generate 32 random characters. Copy the output to your clipboard, then open the configuration file:
- sudo nano docker-compose.yml
Find the HASH_SALT
option, delete the placeholder text, and paste in the random hash you just generated:
. . .
HASH_SALT: replace-me-with-a-random-string
. . .
Next, find the ports:
portion of the configuration:
. . .
ports:
- "127.0.0.1:3000:3000"
. . .
Update the "3000:3000"
value by prepending 127.0.0.1:
to it. This ensures that Umami is only listening on the localhost interface, and is not publicly available. Even though you have a UFW firewall set up, due to some quirks in how Docker networking works, if you didn’t take this step your Umami container would be accessible to the public on port 3000
.
With those configuration changes complete, save the file (CTRL+O
then ENTER
in nano
) and close out of your editor (CTRL+X
).
Now, use docker-compose
to start up your two containers:
- sudo docker-compose up --detach
The --detach
flag tells docker-compose
to create the containers in the background, detached from our terminal session:
Output. . .
Creating umami_db_1 ... done
Creating umami_umami_1 ... done
Umami and PostgreSQL are now running. You can verify this by using the curl
command to fetch the homepage of your new Umami container running on localhost:
- curl localhost:3000
Output<!DOCTYPE html><html><head><meta charSet="utf-8"/> . . .
If a large chunk of HTML is output to your terminal, you know the Umami server is up and running.
Next, we’ll set up Nginx to reverse proxy Umami from localhost:3000
to the public.
Putting a web server such as Nginx in front of your Node.js server can improve performance by offloading caching, compression, and static file serving to a more efficient process. We’re going to install Nginx and configure it to proxy requests to Umami, meaning it will take care of handing requests from your users to Umami and back again.
First, refresh your package list, then install Nginx using apt
:
- sudo apt update
- sudo apt install nginx
Allow public traffic to ports 80
and 443
(HTTP and HTTPS) using the “Nginx Full” UFW application profile:
- sudo ufw allow "Nginx Full"
OutputRule added
Rule added (v6)
Next, open up a new Nginx configuration file in the /etc/nginx/sites-available
directory. We’ll call ours umami.conf
but you could use a different name:
- sudo nano /etc/nginx/sites-available/umami.conf
Paste the following into the new configuration file, being sure to replace your_domain_here
with the domain that you’ve configured to point to your Umami server. This will be something like umami.example.com
, for instance:
server {
listen 80;
listen [::]:80;
server_name your_domain_here;
access_log /var/log/nginx/umami.access.log;
error_log /var/log/nginx/umami.error.log;
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
This configuration is HTTP-only for now, as we’ll let Certbot take care of configuring SSL in the next step. The rest of the config sets up logging locations and then passes all traffic along to http://localhost:3000
, the Umami instance we started up in the previous step.
Save and close the file, then enable the configuration by linking it into /etc/nginx/sites-enabled/
:
- sudo ln -s /etc/nginx/sites-available/umami.conf /etc/nginx/sites-enabled/
Use nginx -t
to verify that the configuration file syntax is correct:
- sudo nginx -t
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
And finally, reload the nginx
service to pick up the new configuration:
- sudo systemctl reload nginx
Your Umami site should now be available on plain HTTP. Load http://your_domain_here
and it will look like this:
Now that you have your site up and running over HTTP, it’s time to secure the connection with Certbot and Let’s Encrypt certificates.
Thanks to Certbot and the Let’s Encrypt free certificate authority, adding SSL encryption to our Umami app will take only two commands.
First, install Certbot and its Nginx plugin:
- sudo apt install certbot python3-certbot-nginx
Next, run certbot
in --nginx
mode, and specify the same domain you used in the Nginx server_name
config:
- sudo certbot --nginx -d your_domain_here
You’ll be prompted to agree to the Let’s Encrypt terms of service, and to enter an email address.
Afterwards, you’ll be asked if you want to redirect all HTTP traffic to HTTPS. It’s up to you, but this is generally recommended and safe to do.
After that, Let’s Encrypt will confirm your request and Certbot will download your certificate:
OutputCongratulations! You have successfully enabled https://umami.example.com
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=umami.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/umami.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/umami.example.com/privkey.pem
Your cert will expire on 2021-12-06. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
Certbot will automatically reload Nginx to pick up the new configuration and certificates. Reload your site and it should switch you over to HTTPS automatically if you chose the redirect option.
Your site is now secure and it’s safe to log in with the default user admin and password umami
. Please do this immediately, and follow the official first login documentation to get logged in and change your admin password to something more secure.
When you first log in, you’ll see a somewhat bare dashboard:
You have successfully installed and secured your Umami analytics software. In the conclusion of this tutorial you’ll find links to documentation that will get you started with adding your site to Umami, and adding Umami tracking snippet to your site.
In this tutorial, you launched the Umami app and a PostgreSQL database using Docker Compose, then set up an Nginx reverse proxy and secured it using Let’s Encrypt SSL certificates.
Also, you should have logged in and updated the default password already. If not, do that now.
Afterwards, continue with the official documentation to learn how to add a website to Umami, then start collecting data by installing the tracking code on your website.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
I tried it on the local computer and then it worked. If I want to move how do I retrieve the data?
This comment has been deleted