Skip to main content

Open-source alternatives guide

How to Self-Host Umami Analytics 2026

Self-host Umami analytics with Docker, PostgreSQL, HTTPS, backups, and privacy-safe tracking decisions. Updated 2026 setup and verdict.

·OSSAlt Team
Share:
Hero image for How to Self-Host Umami Analytics 2026

TL;DR

Self-host Umami when you want lightweight, privacy-friendly web analytics that you can run on a small VPS without adopting Google Analytics or a heavier product analytics stack. Umami is MIT-licensed, has roughly 37K GitHub stars as of June 2026, and the official Docker example is still a two-service stack: the Umami app plus PostgreSQL.

The practical verdict: Umami is the easiest self-hosted Google Analytics replacement for small teams, agencies, docs sites, and indie SaaS projects that mainly need page views, referrers, devices, locations, custom events, and shareable dashboards. Choose Plausible or Matomo instead if you need deeper reporting, ecommerce attribution, or more mature funnel/goal tooling.

Key Takeaways

  • Best fit: privacy-focused traffic analytics, client reporting, public dashboards, and multi-site portfolios.
  • Stack: one app container plus PostgreSQL; no ClickHouse, Redis, or warehouse required.
  • License: MIT for the open-source repository; verify Cloud terms separately if you buy hosted Umami.
  • Ops cost: a small VPS is enough for low-to-moderate traffic, but backups and upgrades are still your responsibility.
  • Privacy: Umami is cookieless by default, but you still need to document your analytics use and legal basis for your jurisdiction.
  • Main tradeoff: simpler than Plausible and Matomo, but less deep for funnel analysis, ecommerce reporting, and user-level product analytics.

Quick Decision Table

SituationBest choiceWhy
You want the fastest self-hosted analytics launchUmamiThe official Docker Compose path is app + PostgreSQL.
You need conversion funnels and polished marketing reportsPlausibleMore mature marketing-analytics workflow, but a heavier stack when self-hosted.
You need ecommerce analytics, campaign depth, or enterprise reportingMatomoBroader analytics feature set with more operational complexity.
You need session replay, feature flags, or product analyticsPostHogDifferent category: product analytics rather than simple traffic analytics.
You want zero server maintenanceUmami Cloud or Plausible CloudHosting, scaling, and upgrades become the vendor's problem.

What Umami Does Well

Umami is deliberately small. The tracker records page views, referrers, UTM campaigns, browsers, devices, countries, and custom events without setting visitor cookies. That makes it a strong fit for OSSAlt-style guide sites, documentation, side projects, portfolios, and privacy-conscious SaaS landing pages.

The strongest operational advantage is the database footprint. Plausible's self-hosted stack uses PostgreSQL plus ClickHouse; Umami's official Docker Compose file uses only PostgreSQL. If your server already runs Postgres for another app, you can create a dedicated Umami database and user instead of managing another database class.

The second advantage is multi-site tracking. One Umami instance can track many domains. Each website gets its own data-website-id, and teams can share read-only dashboards for clients or stakeholders. If you manage several small sites, that is simpler than keeping separate GA4 properties and consent configuration for every property.

Where Umami Is Not Enough

Do not self-host Umami just because it is lighter than Google Analytics. It is intentionally not a complete marketing analytics suite. If your team depends on funnel reports, campaign attribution, ecommerce revenue, customer journeys, or warehouse exports, test those workflows before switching.

Umami also does not remove all privacy work. Cookieless tracking reduces consent friction in many contexts, but analytics can still be personal data depending on your jurisdiction, configuration, retention policy, and reverse proxy logs. Publish a short analytics note in your privacy policy, avoid storing more event properties than you need, and keep server logs aligned with your retention policy.

Production Architecture

A production Umami setup should have four pieces:

  1. Umami app container from ghcr.io/umami-software/umami.
  2. PostgreSQL database with a dedicated database, user, and volume/backups.
  3. HTTPS reverse proxy such as Caddy, Nginx, or Traefik.
  4. Backup and upgrade routine that treats analytics history as recoverable data, not disposable logs.

The official repository's Docker Compose example currently uses ghcr.io/umami-software/umami:latest, DATABASE_URL, and APP_SECRET. For production, pin a known version after your first successful deploy, generate a strong secret, and keep credentials in an .env file that is not committed.

Docker Compose Setup

Create a project directory on your server:

mkdir -p /opt/umami
cd /opt/umami
openssl rand -hex 32

Create .env:

POSTGRES_PASSWORD=replace-with-a-long-random-password
APP_SECRET=replace-with-output-from-openssl-rand-hex-32
UMAMI_VERSION=latest

Use this Compose file as a practical starting point:

services:
  umami:
    image: ghcr.io/umami-software/umami:${UMAMI_VERSION:-latest}
    container_name: umami
    restart: unless-stopped
    init: true
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      DATABASE_URL: postgresql://umami:${POSTGRES_PASSWORD}@db:5432/umami
      APP_SECRET: ${APP_SECRET}
      DISABLE_TELEMETRY: "1"

    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "curl -fsS http://localhost:3000/api/heartbeat || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 5

  db:
    image: postgres:16-alpine
    container_name: umami-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - umami_db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U umami -d umami"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  umami_db:

Start the stack:

docker compose up -d
docker compose ps

Visit http://your-server:3000 through an SSH tunnel or after adding HTTPS. The default login is publicly documented as admin / umami; change it immediately in the profile settings before adding websites.

HTTPS with Caddy

Point analytics.yourdomain.com at the server and install Caddy. Then bind Umami to localhost and let Caddy terminate TLS:

analytics.yourdomain.com {
    reverse_proxy 127.0.0.1:3000
}

Open only SSH, HTTP, and HTTPS at the firewall:

ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Do not expose Umami's port 3000 directly to the public internet if Caddy is your intended entrypoint.

Add Your First Website

In Umami, go to Settings → Websites → Add website, create a website entry, and copy the tracking snippet. For a plain HTML page it looks like this:

<script
  async
  defer
  data-website-id="your-website-id"
  src="https://analytics.yourdomain.com/script.js">
</script>

For a Next.js App Router project, add it with next/script after hydration:

import Script from 'next/script';

export function UmamiScript() {
  return (
    <Script
      async
      defer
      data-website-id={process.env.NEXT_PUBLIC_UMAMI_ID}
      src="https://analytics.yourdomain.com/script.js"
      strategy="afterInteractive"
    />
  );
}

If you run many sites, standardize the script URL and keep only the website ID different per project. That makes audits and privacy-policy updates easier.

Custom Events Without Over-Collecting

Custom events are useful for signups, outbound CTA clicks, search usage, and form starts. Keep event names boring and stable:

<button
  data-umami-event="signup_click"
  data-umami-event-plan="starter">
  Start trial
</button>

Or track from JavaScript:

window.umami?.track('outbound_click', {
  destination_domain: 'example.com',
  link_position: 'guide_cta',
});

Do not send raw emails, names, access tokens, full search queries, or anything you would not want in an analytics database. Umami makes event properties easy to add; that convenience can turn a privacy-friendly setup into unnecessary data collection if you are not deliberate.

Backup, Update, and Rollback Routine

Analytics history is not as critical as customer data, but trend history is still valuable. Back up PostgreSQL before upgrades and at least nightly for production sites:

mkdir -p /opt/backups/umami
docker exec umami-db pg_dump -U umami umami | gzip > /opt/backups/umami/umami-$(date +%Y%m%d).sql.gz

Update with a reversible sequence:

# 1. Backup first
docker exec umami-db pg_dump -U umami umami | gzip > /opt/backups/umami/pre-upgrade-$(date +%Y%m%d).sql.gz

# 2. Pull and restart
docker compose pull
docker compose up -d

# 3. Verify health and recent page views
docker compose ps
docker compose logs --tail=100 umami

For a production team, pin UMAMI_VERSION to a tested release rather than running latest forever. Test the new version on staging or a cloned database when analytics continuity matters.

Troubleshooting Checklist

The dashboard loads but no visits appear. Open browser developer tools and confirm the script loads from your analytics domain. Then check for requests to Umami's collect endpoint. Most failures are a wrong data-website-id, a script tag copied from the wrong website entry, or a CSP rule that blocks the analytics domain.

The app starts before PostgreSQL is ready. Keep depends_on plus the database health check. If the database volume was initialized with old credentials, changing .env alone will not change the existing Postgres user's password.

Users still get blocked by ad blockers. Serving the tracker from your own domain helps, but some filter lists still recognize analytics patterns. If measurement accuracy is business-critical, document the expected undercount rather than trying to evade every blocker.

The dashboard is slow on a large site. Umami's PostgreSQL-backed reports are fine for small-to-medium traffic. For very high event volume, budget for database tuning, retention decisions, and possibly hosted analytics. A tiny VPS is not the right long-term home for tens of millions of monthly events.

Final Verdict

Self-host Umami if you want the lowest-friction open-source analytics stack that still gives useful traffic reports and custom events. It is especially strong for small websites, agencies, privacy-minded SaaS teams, and self-hosters who already understand Docker and PostgreSQL.

Skip Umami if your analytics requirements are closer to product analytics, ecommerce attribution, or advanced marketing operations. In that case, compare Plausible vs Umami vs Matomo, review the best open-source analytics tools, and decide from your reporting workflow rather than from installation simplicity alone.

Sources Checked

See all open source Google Analytics alternatives at OSSAlt.com/alternatives/google-analytics.

See open source alternatives to Umami on OSSAlt.

The SaaS-to-Self-Hosted Migration Guide (Free PDF)

Step-by-step: infrastructure setup, data migration, backups, and security for 15+ common SaaS replacements. Used by 300+ developers.

Join 300+ self-hosters. Unsubscribe in one click.