웹사이트를 운영하면 방문자 통계가 궁금해진다. 그런데 구글 애널리틱스를 넣는 순간, 방문자 정보는 구글 서버로 나가고 쿠키 동의 배너를 달아야 하고, 애드블로커 사용자는 아예 안 잡힌다. Umami는 이 트레이드오프를 바꾸는 오픈소스 애널리틱스다. 추적 스크립트가 2KB 미만, 쿠키 불사용, 데이터는 내 데이터베이스에만 쌓인다.
필요한 것은 서버와 작은 데이터베이스뿐이다. 구독료도, 데이터 유출 걱정도 없다.
Umami는 프라이버시 중심의 경량 웹 애널리틱스 오픈소스다. 구글 애널리틱스(GA)의 대안으로 가장 많이 언급되는 제품 중 하나로, "최소한의 수집으로 최대한의 인사이트"라는 철학이 뚜렷하다.
GA와의 차이를 표로 정리하면:
| 항목 | 구글 애널리틱스 | Umami |
|---|---|---|
| 데이터 위치 | 구글 클라우드 | 내 데이터베이스 |
| 쿠키 | 사용 (동의 배너 필요) | 미사용 |
| 추적 스크립트 크기 | 수십 KB | 2KB 미만 |
| 애드블로커 | 대부분 차단당함 | 스크립트 이름 변경으로 회피 가능 |
| 화면 구성 | 복잡 (기능 방대) | 단순 (핵심만) |
| 비용 | 무료(데이터는 구글 소유) | 무료(데이터는 내 소유) |
제공되는 지표: 페이지뷰·방문자(순방문자)·세션 시간, 유입 경로(검색·SNS·직접), 페이지별 조회, 브라우저·OS·기기, 국가, 실시간 접속, 그리고 이벤트 추적(버튼 클릭 같은 사용자 행동)까지. 일상적인 사이트 운영에 필요한 지표는 전부다.
구성이 이 시리즈에서 가장 단순한 축에 속한다.
flowchart LR
V["방문자 브라우저"] -->|추적 스크립트 응답| UM
subgraph SRV["Docker 서버"]
UM["Umami - 수집과 대시보드"]
PG[("PostgreSQL - 통계 데이터")]
end
A["사이트 운영자 - 통계 화면"]
V --> UM
UM --> PG
PG --> A
방문자의 브라우저가 1픽셀짜리 요청을 Umami로 보내고, Umami는 이를 데이터베이스에 기록한다. 운영자는 Umami의 대시보드에서 그 기록을 본다. 쿠키가 없으므로 방문자 구분은 익명화된 조합(사용자 에이전트·IP 해시 등)으로만 이뤄진다.
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
environment:
DATABASE_TYPE: postgresql
DATABASE_URL: postgresql://umami:DB비밀번호@umami-db:5432/umami
APP_SECRET: 랜덤문자열 # 설치 시 생성되는 해시 값, 꼭 변경
TRACKER_SCRIPT_NAME: my-stats # 선택: 애드블로커 회피용 스크립트명
ports:
- "3100:3000"
depends_on:
- umami-db
umami-db:
image: postgres:16
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: DB비밀번호
volumes:
- ./pgdata:/var/lib/postgresql/data
기동 후 http://서버IP:3100 접속. 초기 계정은 admin / umami이니 첫 로그인 후 즉시 비밀번호를 바꾼다.
설정 → 웹사이트 추가에서 사이트를 등록하면 추적 코드가 발급된다:
<script async src="https://stats.example.com/script.js" data-website-id="발급된ID"></script>
이 한 줄을 측정할 사이트의 </head> 앞에 넣으면 통계 수집이 시작된다. 도메인을 붙여 HTTPS로 서비스하는 것을 권장한다 — 프록시 뒤에서는 접속 도메인과 설정이 일치해야 추적 스크립트 주소도 정상 나온다.
페이지뷰 외에 원하는 행동을 지정해 세고 싶다면(버튼 클릭, 다운로드 등):
<button onclick="umami.track('견적문의-클릭')">견적 문의</button>
이벤트 탭에서 이름별 집계가 바로 보인다. "오늘 견적 문의 버튼이 몇 번 눌렸나"를 애널리틱스 도구 관점에서 무료로, 프라이버시 부담 없이 얻는 셈이다.
추적 스크립트 이름 바꾸기는 실질적이다. 기본값 script.js는 애드블로커 차단 목록에 등록돼 있다. TRACKER_SCRIPT_NAME을 바꾸면 차단율이 눈에 띄게 떨어진다 — 다만 애드블로커를 쓰는 방문자의 의사를 존중하는 게 원칙인 만큼, 통계의 완전성을 위한 선택지 정도로 이해하자.
데이터 보존 기간을 정해두자. 통계 DB는 시간이 지나면 계속 불어난다. 설정에서 데이터 보존 기간(예: 1년)을 정해두면 자동 정리된다.
GA에서 이전할 때 마음가짐. Umami에는 GA의 방대한 기능(광고 연동, 퍼널, 코호트)이 없다. 대신 "어제 몇 명이 왔고, 어디서 왔고, 뭘 봤는가"라는 운영의 본질 질문에는 몇 초 안에 답한다. 도구가 단순해지면 중요한 숫자에 집중하게 된다.
| 증상 | 원인 | 해결 |
|---|---|---|
| 통계가 전혀 안 잡힌다 | 추적 코드 미삽입·도메인 불일치 | 스크립트 태그 위치와 주소 확인 |
| 내 방문만 잡힌다 | 캐시된 페이지에 추적 코드 없음 | 캐시 정리 후 재확인 |
| 이벤트가 안 잡힌다 | 함수명·웹사이트 ID 불일치 | umami.track 구문과 등록된 사이트 확인 |
| 방문자 수가 과소 집계된다 | 애드블로커 차단 | TRACKER_SCRIPT_NAME 변경 |
| 통계 DB가 계속 불어난다 | 보존 기간 미설정 | 설정에서 보존 기간 지정 |
핵심 지표는 전부 있고, 고급 마케팅 분석(광고 플랫폼 연동 등)은 없다. 대신 데이터 주권, 쿠키 불사용, 속도 — 이 세 가지가 필요하면 Umami가 답이다. 많은 사이트가 GA의 기능 중 실제로 보는 건 몇 개 안 되기도 하다.
매 방문의 사용자 에이전트·IP 등을 해시해 익명 식별자를 만들고, 일정 기간 뒤 같은 해시가 나오면 재방문으로 센다. 개인을 재식별할 수 없는 방식이라 쿠키 동의 배너 대상이 아닌 것으로 취급되는 경우가 많다(단, 지역 법규 확인은 운영자 책임).
웹사이트를 여러 개 등록해 각각 추적 코드를 발급하면 된다. 팀 공유도 계정으로 관리된다.
서버 한 대로 충분하다 연재 목차 — 시리즈 소개 · 1화. Home Assistant · 2화. Frigate + go2rtc · 3화. Seafile 13 · 4화. Immich · 5화. Vaultwarden · 6화. Mailcow
실제 운영 사이트 통계로 사용 중인 구성입니다.
| 이전 | 7화. MinIO — S3 API를 내 방에. 오브젝트 스토리지 입문 | 2026-10-01 | |
|---|---|---|---|
| 다음 | 9화. GitLab — 혼자 개발해도 CI/CD는 갖춘다 (셀프호스팅) | 2026-10-01 |