• Self-host Umami on Oracle Cloud for free

    Umami is an open-source, privacy-focused web analytics tool that serves as an alternative to Google Analytics. Its free plan comes with certain limits — including 6 months of data retention, support for up to 3 websites, and a cap of 100,000 events per month. However, you can self-host Umami on your own server to access all its features without paying a dime.

    In this tutorial, I’ll walk you through how to self-host Umami on Oracle Cloud (OCI), using their Free Tier resources. For the tech stack, we’ll use Nginx as web server, Cloudflare SSL, and Docker Compose for deployment. Now let’s begin.

    Launch a new Instance on OCI

    Refer to this article for instructions on how to launch a new Instance on OCI. When configuring the instance, allocate at least 1 OCPU and 2GB of RAM to ensure Umami runs smoothly.

    Prepare a domain or sub-domain

    You must have a domain or sub-domain to access Umami, for example, yourdomain.com or data.yourdomain.com. And point its DNS record to the instance’s public IP address.

    In the Instances dashboard of Oracle, you can see the Public IP of each Instance. Use your DNS manager (in this case is Cloudflare) to point to this IP.

    Install Docker and Docker Compose

    We’ll use Docker Compose to deploy the whole Umami package — including Umami itself and PostgreSQL.

    Connect to your server via SSH.

    Update and upgrade your server:

    sudo apt update && sudo apt upgrade -y
    Code language: Bash (bash)

    Install necessary packages for Docker:

    sudo apt install -y curl ca-certificates apt-transport-https software-properties-common
    Code language: Bash (bash)

    Add new official GPG Key to verify the authenticity of Docker’s repository to ensure you’re downloading trusted software:

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    sudo install -m 0755 -d /usr/share/keyrings/
    Code language: Bash (bash)

    Verify the repo:

    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    Code language: Bash (bash)

    Update the packages list:

    sudo apt update
    Code language: Bash (bash)

    Install Docker & Docker Compose:

    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
    Code language: Bash (bash)

    Start Docker:

    sudo systemctl start docker
    Code language: Bash (bash)

    Verify the status of Docker & Docker Compose:

    sudo systemctl status docker
    sudo docker --version
    sudo docker compose version
    Code language: Bash (bash)

    Enable Docker to start on server boot:

    sudo systemctl enable docker
    sudo systemctl enable containerd
    Code language: Shell Session (shell)

    Set up Docker Compose

    In this step, we’ll set up the .env and Docker Compose YAML configuration files. The structure of your Umami project directory should look like this:

    /umami/
       |-- .env
       |-- docker-compose.ymlCode language: Bash (bash)

    Create a new directory for Umami project and switch to it:

    mkdir umami && cd umami
    Code language: Shell Session (shell)

    .env file

    Create new .env file:

    sudo touch .env
    Code language: Bash (bash)

    Set owner and permission for .env file:

    sudo chown ubuntu:ubuntu .env
    sudo chmod 600 .env
    Code language: Bash (bash)

    Open .env file:

    sudo nano .env
    Code language: Bash (bash)

    And paste this content to the file:

    # Umami environment variables
    DATABASE_URL=postgresql://umami_user:umami_pass@db:5432/umami_db
    DATABASE_TYPE=postgresql
    APP_SECRET=your_random_secret_key
    
    # PostgreSQL environment variables
    POSTGRES_DB=umami_db
    POSTGRES_USER=umami_user
    POSTGRES_PASSWORD=umami_passCode language: YAML (yaml)

    And update these parameters:

    • POSTGRES_PASSWORD: change from umami_pass to a strong password.
    • DATABASE_URL: Update your new password to the umami_pass part of the string.

    For the APP_SECRET parameter, you need to enter this command:

    openssl rand -hex 32
    Code language: Bash (bash)

    The terminal will output a string like this (DO NOT COPY this string):

    cedc41a9c7a8c019866d4c38905165f516e089190651ff08f1a01c3b0612fa04Code language: plaintext (plaintext)

    Replace your_random_secret_key with the string generated by the openssl command.

    Press Ctrl + X, then Y to close and save the .env file.

    docker-compose.yml file

    Create and open docker-compose.yml file:

    sudo nano docker-compose.yml
    Code language: Bash (bash)

    Paste this content to that file:

    services:
      umami:
        image: ghcr.io/umami-software/umami:postgresql-latest
        ports:
          - "3000:3000"
        env_file: .env
        environment:
          - DATABASE_URL=${DATABASE_URL}
          - DATABASE_TYPE=${DATABASE_TYPE}
          - APP_SECRET=${APP_SECRET}
        depends_on:
          - db
        restart: always
        networks:
          - umami-net
      db:
        image: postgres:latest
    	env_file: .env
        environment:
          - POSTGRES_DB=${POSTGRES_DB}
          - POSTGRES_USER=${POSTGRES_USER}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
        volumes:
          - umami-db-data:/var/lib/postgresql/data
        restart: always
        networks:
          - umami-net
    networks:
      umami-net:
        driver: bridge
    volumes:
      umami-db-data:
    Code language: YAML (yaml)

    Change its permission:

    sudo chmod 600 docker-compose.yml
    Code language: Bash (bash)

    Start Umami:

    sudo docker compose up -d
    Code language: Bash (bash)

    Install Nginx

    Enter these commands to install Nginx and enable it to start on server boot:

    sudo apt install nginx -y
    sudo systemctl start nginx
    sudo systemctl enable nginx
    Code language: Shell Session (shell)

    Create and open the Nginx configuration file for Umami:

    sudo nano /etc/nginx/sites-available/umami
    Code language: Bash (bash)

    Paste this content to that file:

    server {
        listen 80;
        server_name yourdomain.com;
            
        # Deny access to .env files
        location ~* \.env$ {
            deny all;
            return 403;
        }
    	
        return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl;
        server_name yourdomain.com;
            
        # Deny access to .env files
        location ~* \.env$ {
            deny all;
            return 403;
        }
            
        # Reverse proxy to Umami (Docker container)
        location / {
            proxy_pass http://localhost:3000;
            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;
        }
    	
        # Logs
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
            
        # SSL certificate
        ssl_certificate /etc/ssl/certs/cloudflare.pem;
        ssl_certificate_key /etc/ssl/private/cloudflare.key;
    	
        # Security headers
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Content-Type-Options "nosniff";
        add_header Referrer-Policy "strict-origin-when-cross-origin";
        add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://icons.duckduckgo.com; connect-src 'self';";
    }
    Code language: Nginx (nginx)

    Update your server_name (line 3, 16).

    For the SSL certificate files (line 38, 39), refer to this article for instructions on how to obtain them.

    Press Ctrl + X, then Y to close and save the file.

    Activate the above configuration by linking that config file to the sites-enableddirectory:

    sudo ln -s /etc/nginx/sites-available/umami /etc/nginx/sites-enabled/
    Code language: Bash (bash)

    Remove the default config file:

    sudo rm /etc/nginx/sites-enabled/default
    Code language: Bash (bash)

    Check the Nginx syntax and reload it:

    sudo nginx -t
    sudo systemctl reload nginx
    Code language: Bash (bash)

    Now you can visit yourdomain.com to use Umami. The default login credentials are:

    username: admin
    password: umamiCode language: plaintext (plaintext)

    After logging in, change your password in the Umami’s Settings.

    Done.

    Top ↑