🧠 Why This Guide?

Umami is a powerful, open-source, privacy-first alternative to Google Analytics. It’s lightweight, cookie-free, and beautifully designed.

This guide walks you through hosting Umami for free on a t2.micro EC2 instance, and exposing it at your own custom subdomain (e.g., https://umami.misomash.com) — without needing a public IP or reverse proxy.

No NGINX. No domain linking. No bills.


✅ What You'll Achieve

  • 🧭 Umami dashboard running on AWS Free Tier
  • 🔐 Accessible at https://umami.misomash.com
  • 💵 No cost: no domain, no paid plan, no SSL needed
  • ⚙️ Automated restart on reboot

🔧 What You'll Need

  • AWS account (Free Tier)
  • Cloudflare account (Free)
  • Basic command line comfort
  • A domain in Cloudflare (e.g. misomash.com)
  • 45 minutes of time

🛠️ Step 1 — Launch a Free EC2 Instance

  1. Go to AWS EC2
  2. Click Launch Instance
  3. Choose:
    • AMI: Ubuntu 22.04
    • Instance Type: t2.micro (Free Tier eligible)
    • Storage: 8 GB is enough
  4. Create a new Security Group and open these ports:
    • TCP 22 (SSH)
    • TCP 80 (HTTP)
    • TCP 443 (HTTPS)
    • TCP 3000 (for Umami’s default port)
  5. Launch the instance and connect via SSH

🐳 Step 2 — Install Docker & Docker Compose

SSH into your instance and run:

sudo apt update
sudo apt upgrade -y
sudo apt install -y docker.io docker-compose
sudo systemctl enable docker
sudo systemctl start docker

📦 Step 3 — Deploy Umami with Docker Compose

Create a folder and write the config:

mkdir ~/umami && cd ~/umami
nano docker-compose.yml

Paste this:

version: "3"

services:
  umami-db:
    image: postgres:15
    restart: always
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: umami
    volumes:
      - db-data:/var/lib/postgresql/data

  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    restart: always
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://umami:umami@umami-db:5432/umami
      APP_SECRET: your-secret-key
    depends_on:
      - umami-db

volumes:
  db-data:

Save (Ctrl+O, Enter), then start the app:

sudo docker-compose up -d

🌍 Step 4 — Install Cloudflare Tunnel

Install the CLI:

wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb

Authenticate with Cloudflare:

cloudflared tunnel login

This will open a browser window. Log into your Cloudflare account and approve the authentication.


🔐 Step 5 — Create a Permanent Tunnel

Create the tunnel:

cloudflared tunnel create umami-tunnel

This creates a .json credential file like:

/home/ubuntu/.cloudflared/<tunnel-id>.json

🌐 Step 6 — Configure the Tunnel

sudo mkdir -p /etc/cloudflared
sudo nano /etc/cloudflared/config.yml

Paste (replace with your actual tunnel ID and file name):

tunnel: <your-tunnel-id>
credentials-file: /home/ubuntu/.cloudflared/<tunnel-id>.json

ingress:
  - hostname: umami.misomash.com
    service: http://localhost:3000
  - service: http_status:404

Save and exit.


🌐 Step 7 — Add DNS Record in Cloudflare

In your Cloudflare dashboard:

  1. Go to your domain misomash.com
  2. Go to DNS
  3. Add a new record:
  • Type: CNAME
  • Name: umami
  • Target: <your-tunnel-id>.cfargotunnel.com
  • Proxy: Proxied (orange cloud)

🚀 Step 8 — Start the Tunnel

sudo systemctl restart cloudflared

Or enable it at boot:

sudo cloudflared service install

Now visit:

👉 https://umami.misomash.com

You should see the Umami login screen 🎉


🔄 Step 9 — Auto-start Umami on Reboot

Create a systemd service:

sudo nano /etc/systemd/system/umami.service

Paste:

[Unit]
Description=Umami Analytics
After=docker.service
Requires=docker.service

[Service]
WorkingDirectory=/home/ubuntu/umami
ExecStart=/usr/bin/docker-compose up -d
ExecStop=/usr/bin/docker-compose down
Restart=always
User=ubuntu

[Install]
WantedBy=multi-user.target

Enable it:

sudo systemctl daemon-reload
sudo systemctl enable umami

✅ You Now Have:

  • 🔐 A secure, HTTPS Umami dashboard at umami.misomash.com
  • 🔁 Auto-starting containers and tunnel on reboot
  • 🧠 Full ownership of your analytics