V dnešní době je soukromí na internetu velké téma. Pokud provozujete webové stránky, pravděpodobně chcete vědět, kolik lidí je navštěvuje, odkud přicházejí, jaký obsah je nejpopulárnější. Google Analytics je často používané řešení, ale co když nechcete svá data svěřovat velké korporaci? Co když chcete mít plnou kontrolu nad analytickými daty a zajistit, že nebudou zneužita pro cílení reklam nebo sledování uživatelů?
Přesně to byl můj případ. Zkouším open-source nástroj na vlastní infrastruktuře. Vybral jsem Umami a Cloudflare Tunnel pro bezpečné zpřístupnění světu. V tomto článku vás provedu celým procesem.
Co je Umami?
Umami je moderní, jednoduchý a open-source nástroj pro webovou analytiku. Jeho hlavními výhodami jsou:
- Zaměření na soukromí: Nesbírá žádné osobní údaje, nepoužívá cookies a je plně v souladu s GDPR, … Není potřeba žádný otravný cookie banner jen kvůli analytice.
- Vlastnictví dat: Protože si Umami hostuji sám, mám 100% kontrolu nad svými daty.
- Jednoduchost: Nabízí přehledné rozhraní a poskytuje všechny klíčové metriky bez zbytečné komplexity.
- Nízká zátěž: Je napsaný v Node.js a je velmi lehký a rychlý. Sledovací skript má jen pár kilobajtů.
- Open Source: Můžete si kód prohlédnout, upravit a přispět jeho rozvoji.
Než začneme, budete potřebovat
- Server nebo virtuální stroj (např. v rámci Home Labu), kde běží Docker.
- Nainstalovaný Portainer (volitelné, ale usnadňuje správu Docker kontejnerů – v tomto návodu jej používám).
- Účet u Cloudflare a doménu spravovanou přes Cloudflare (postačí DNS zóna).
- Základní znalost práce s příkazovou řádkou a Dockerem.
Krok 1: Nasazení Umami (Docker Compose a Portaineru)

Pro správu Docker kontejnerů aktuálně zkouším Portainer.
- Přihlaste se do Portaineru.
- Přejděte do sekce Stacks.
- Klikněte na + Add stack.
- Pojmenujte stack, například
umami
. - Do Web editoru vložte následující
docker-compose.yml
konfiguraci:
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- "3000:3000" # Můžete změnit vnitřní port, pokud 3000 již používáte
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
DATABASE_TYPE: postgresql
APP_SECRET: ${APP_SECRET} # Důležité pro bezpečnost session!
depends_on:
db:
condition: service_healthy
init: true
restart: always
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/heartbeat || exit 1"]
interval: 30s
timeout: 10s
retries: 3
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- umami_db_data:/var/lib/postgresql/data
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
volumes:
umami_db_data:
-
Nyní je potřeba nastavit Environment variables (proměnné prostředí) pro tento stack v Portaineru:
-
POSTGRES_DB
: Zvolte název databáze pro Umami (např.umami_db
). -
POSTGRES_USER
: Zvolte uživatelské jméno pro přístup k databázi (např.umami_user
). -
POSTGRES_PASSWORD
: Vygenerujte silné a bezpečné heslo pro databázového uživatele. -
APP_SECRET
: Vygenerujte náhodný řetězec (salt), který Umami používá pro zabezpečení. Můžete použít příkaz v terminálu:openssl rand -base64 32
Výstup zkopírujte a vložte jako hodnotu pro
APP_SECRET
.
-
-
Klikněte na Deploy the stack. Portainer stáhne potřebné image a spustí kontejnery pro Umami a PostgreSQL databázi.
Po úspěšném spuštění by měla být aplikace Umami dostupná na adrese vašeho serveru na portu 3000 (např. http://<IP_ADRESA_SERVERU>:3000
).
První přihlášení a zabezpečení
Výchozí přihlašovací údaje jsou:
- Uživatelské jméno:
admin
- Heslo:
umami
Důležité: Po prvním přihlášení si okamžitě změňte heslo na silné a unikátní v nastavení profilu!
Krok 2: Vytvoření Cloudflare Zero Trust Tunnel

Aby byla instance Umami bezpečně dostupná z internetu (pro sběr dat z webů a pro přístup k dashboardu) a abychom nemuseli otevírat porty na firewallu, zvěřejnit svou IP adresu, použijeme Cloudflare Tunnel.
- Přihlaste se do Cloudflare Dashboard.
- Vyberte doménu a přejděte do sekce Zero Trust (pokud ji nemáte aktivovanou, Cloudflare vás provede rychlým nastavením plánu).
- V Zero Trust dashboardu jděte do Networks -> Tunnels.
- Klikněte na + Create a tunnel.
- Vyberte typ konektoru Cloudflared. Klikněte na Next.
- Zadejte název tunelu (např.
umami-tunnel
). Klikněte na Save Tunnel. - Nyní Cloudflare zobrazí příkazy pro instalaci
cloudflared
konektoru. Protože jej spouštím v Dockeru, vyberu záložku Docker. Zobrazí se příkaz obsahující unikátní token tunelu. Tento token si zkopíruji a bezpečně uložím (za chvíli bude potřeba).
docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <TOKEN>
- V sekci Public Hostnames klikněte na + Add public hostname:
- Subdomain: Subdoména, na které bude Umami dostupné (např.
stats
neboumami
). - Domain: Vyberte doménu ze seznamu. Výsledná adresa bude např.
stats.vasedomena.cz
. - Service - Type: Vyberte
HTTP
. - Service - URL: Zadejte
host.docker.internal:3000
.- Poznámka:
host.docker.internal
je speciální DNS název v rámci Dockeru, který umožňuje kontejneru (cloudflared
) komunikovat se službou běžící na hostitelském stroji (nebo v jiném kontejneru vystaveném na hostitelském portu). Port3000
je ten, který jsme nastavili pro Umami v předchozím kroku.
- Poznámka:
- Subdomain: Subdoména, na které bude Umami dostupné (např.
- Klikněte na Save tunnel. Tím je tunel nakonfigurován na straně Cloudflare.
Krok 3: Spuštění Cloudflared kontejneru v Portaineru
Nyní vytvoříme další stack v Portaineru pro cloudflared
konektor, který se připojí k Cloudflare a bude směrovat provoz.
- V Portaineru jděte opět do Stacks -> + Add stack.
- Pojmenujte stack, například
cloudflared
. - Vložte následující
docker-compose.yml
obsah:
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: unless-stopped
environment:
- TZ=Europe/Prague # Nastavte časovou zónu
- TUNNEL_TOKEN=${TUNNEL_TOKEN} # Zde vložíme token z Cloudflare
command: tunnel --no-autoupdate run
# Tato sekce je důležitá, aby cloudflared viděl služby na hostiteli
extra_hosts:
- "host.docker.internal:host-gateway"
- V sekci Environment variables přidejte proměnnou:
TUNNEL_TOKEN
: Vložte sem ten dlouhý token, který jsme získali při vytváření tunelu v Cloudflare dashboardu. - Nastavte správnou časovou zónu (TZ).
- Klikněte na Deploy the stack.
Pokud vše proběhlo v pořádku, kontejner cloudflared
se spustí, připojí se k Cloudflare pomocí vašeho tokenu a váš tunel bude aktivní.
Krok 4: Přidání webu do Umami a získání Tracking kódu

Nyní zaregistrujeme web v Umami instanci.
- Otevřete Umami instanci přes Cloudflare Tunnel adresu (např.
https://stats.vasedomena.cz
) a přihlaste se. - Přejděte do Settings -> Websites -> + Add website.
- Vyplňte Název (Name) webu (libovolný, pro snadnou identifikaci) a Doménu (Domain) webu (např.
www.mojedomena.cz
). - Klikněte na Save.
- Po uložení se web objeví v seznamu. Klikněte na
Upravit
a zobrazí se Vám nastavení, kde uvidíteWebsite ID
a na vedlejší záložce i celý sledovací kód. Tento kód budete potřebovat v dalším kroku. Všimněte si dvou klíčových částí:- Adresa skriptu (atribut
src
): Napříkladhttps://stats.vasedomena.cz/script.js
. - Website ID (atribut
data-website-id
): Unikátní identifikátor vašeho webu v Umami (dlouhý řetězec písmen a čísel).
- Adresa skriptu (atribut
Krok 5: Integrace Tracking kódu do webu (příklad pro Hugo)
Pokud web běží na generátoru Hugo, stejně jako můj blog, můžete sledovací kód integrovat elegantně pomocí konfigurace a partial šablony.
Konfigurace v config.yaml
(nebo config.toml
)
Otevřete hlavní konfigurační soubor Hugo projektu (config.yaml
, hugo.yaml
nebo config.toml
- syntaxe se mírně liší, zde příklad pro YAML). Do sekce params
přidejte následující blok:
params:
# ... vaše ostatní parametry ...
umami:
script: "https://stats.vasedomena.cz/script.js" # Nahraďte vaší URL Umami skriptu
websiteID: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Nahraďte vaším skutečným Website ID z Umami
# ... další parametry ...
Důležité: Nahraďte URL v script
adresou vašeho Umami skriptu a websiteID
vaším unikátním identifikátorem získaným v kroku 4.
Vytvoření Partial šablony pro vložení do <head>
Mnoho Hugo témat umožňuje rozšířit HTML hlavičku (<head>
) pomocí partial šablony. Standardní název pro takovou šablonu bývá extend_head.html
.
-
Ve struktuře vašeho Hugo projektu vytvořte (pokud neexistuje) soubor:
layouts/partials/extend_head.html
-
Do tohoto souboru vložte následující řádek:
{{/* Umami Tracking Code - loaded if configured in params */}} {{ if and .Site.Params.umami.script .Site.Params.umami.websiteID }} <script defer src="{{ .Site.Params.umami.script }}" data-website-id="{{ .Site.Params.umami.websiteID }}"></script> {{ end }}
- Použití
defer
zajistí, že se skript načte asynchronně a nebude blokovat vykreslování stránky. - Podmínka
{{ if ... }}
zajistí, že se skript vloží pouze tehdy, pokud jsou vconfig.yaml
vyplněny obě hodnoty (script
awebsiteID
).
Poznámka: Ujistěte se, že vaše Hugo téma skutečně volá partial
extend_head.html
ve své hlavní šabloně hlavičky (obvykle vlayouts/_default/baseof.html
nebo podobném souboru, hledejte něco jako{{ partial "extend_head.html" . }}
). Pokud ne, budete muset výše uvedený<script>
tag vložit přímo do příslušné šablony vašeho tématu v rámci<head>
tagu. - Použití
Nasazení změn
- Znovu sestavte svůj Hugo web pomocí příkazu
hugo
v terminálu. - Nasaďte vygenerované soubory (obvykle z adresáře
public
) na váš webhosting.
Krok 6: Ověření a závěr
Po nasazení změn na webu otevřete web v prohlížeči (ideálně v anonymním okně, abyste neměli cachovaný obsah). Můžete také použít vývojářské nástroje prohlížeče (klávesa F12) a na záložce “Network” (Síť) zkontrolovat, zda se úspěšně načítá váš Umami script.js
.
Pokud je vše OK, ihned uvidíte první data o návštěvnosti webu na Umami dashboardu.
Úspěšně jsme nastavili vlastní, na soukromí zaměřenou webovou analytiku pomocí Umami, Dockeru a Cloudflare Tunnel. Máme data o návštěvnosti webu, aniž bychom je museli sdílet s třetími stranami.