별고래 분석실 — Umami로 방문자 통계

작성자

카테고리:

This post is written in Korean. Most browsers (Chrome, Edge) can translate it automatically — look for a translate icon in the address bar, or right-click the page and choose “Translate to English.”

셀프호스팅 구축기 5편. 데이터 주권을 미니PC로 가져오기.

← 이전 편: 4편 — 자기 PC가 알아서 (백업·캐시·압축)
→ 다음 편: 6편 — 도메인 사기: Cloudflare Registrar


TL;DR

  • Google Analytics 무료 = 주인장 방문자 데이터를 Google 서버에 줌 + 쿠키 동의 팝업 강제
  • Umami self-hosted = 미니PC에 자체 분석. 쿠키 0, 데이터 본인 소유, GDPR 자동 면제
  • Docker Compose 5분. WP에 트래커 한 줄 자동 주입 = 끝
  • 화면: 방문자 수·인기 글·유입 경로·기기·국가·체류 시간

1. Google Analytics의 보이지 않는 비용

항목 Google Analytics 4 Umami self-hosted
비용 무료 (개인 사용) 무료 (오픈소스)
데이터 소유 Google 본인 미니PC
쿠키 동의 팝업 필수 (GDPR/CCPA) 불필요 (쿠키 0)
페이지 로딩 부하 ~50KB JS ~2KB JS
사용자 추적 크로스 사이트 (Google 광고 연계) 같은 사이트 내만
한국 PIPA 대응 까다로움 자동 면제
설정 복잡도 1시간+ 5분

Google Analytics는 진짜 비용을 사용자(방문자)에게 외부화한다. 방문자가 주인장 사이트 들어왔다고 Google이 그 데이터 다 받아가는 게 정상인가? 1인 블로그라면 우리가 직접 운영하는 게 옳다.

구글 애널리틱스와 셀프호스팅 Umami — 방문 기록이 어디로 가나 왼쪽은 Google Analytics 4. 방문자 브라우저가 내 블로그에서 페이지를 받는 동시에 방문 기록을 Google 서버로 보낸다. Google 서버는 내 영역 밖에 있고 크로스 사이트 추적, 즉 Google 광고와 연계된다. 쿠키 동의 팝업이 필수이고 데이터 소유는 Google, 페이지 로딩 부하는 약 50KB 자바스크립트다. 오른쪽은 셀프호스팅 Umami. 방문 기록이 내 미니PC 안의 Umami로 가고 Postgres에 저장되어 데이터가 밖으로 나가지 않는다. 쿠키가 0개라 동의 팝업이 필요 없고, 데이터는 본인 미니PC 소유, 페이지 로딩 부하는 약 2KB 자바스크립트다. Google Analytics 4 방문자 브라우저 내 영역 페이지 방문 기록 내 블로그 WordPress Google 서버 데이터가 밖으로 크로스 사이트 추적 (Google 광고 연계) 쿠키 동의 팝업 필수 데이터 소유 Google 페이지 로딩 부하 ~50KB JS Umami self-hosted 방문자 브라우저 내 미니PC — 데이터가 밖으로 안 나감 페이지 방문 기록 내 블로그 WordPress Umami 쿠키 0 Postgres 쿠키 동의 팝업 불필요 (쿠키 0) 데이터 소유 본인 미니PC 페이지 로딩 부하 ~2KB JS
그림 1. 구글 애널리틱스는 방문 기록이 Google 서버로 나가고, 셀프호스팅 Umami는 내 미니PC 안에 남는다 (1장 표의 항목 그대로).

2. 구조

방문자 브라우저가 별고래 페이지 받으면 head의 <script defer src="https://analytics.sticknstone.org/script.js" data-website-id="..."> 가 실행 → Umami에 비동기 요청 → Umami가 Postgres에 기록. 페이지 표시는 안 막힘.

방문 한 번이 기록되는 경로 방문자 브라우저가 별고래 페이지를 요청하면 WordPress가 페이지를 돌려주는데, head에는 mu-plugin이 자동으로 넣은 트래커 한 줄이 들어 있다. 로그인한 사용자에게는 넣지 않는다. 브라우저는 그 스크립트를 defer로 실행해 analytics.sticknstone.org의 Umami에 비동기 요청을 보내므로 페이지 표시는 막히지 않는다. Umami는 방문을 Postgres에 기록한다. WordPress, Umami, Postgres는 모두 미니PC 안에 있다. 미니PC 방문자 브라우저 별고래 페이지 (WordPress) head에 트래커 1줄 자동 주입 mu-plugin · 로그인 사용자는 제외 ① 페이지 요청 ② 페이지 + 트래커 1줄 Umami analytics.sticknstone.org ③ 비동기 요청 페이지 표시 안 막힘 Postgres umami_db ④ 기록
그림 2. 방문 한 번이 기록되는 경로. 트래커는 defer로 따로 돌기 때문에 페이지 표시를 기다리게 하지 않는다.

3. Docker Compose

/home/user/umami/docker-compose.yml:

services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      DATABASE_URL: postgresql://umami:${DB_PASSWORD}@db:5432/umami
      DATABASE_TYPE: postgresql
      APP_SECRET: ${APP_SECRET}
    ports:
      - "3001:3000"

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

volumes:
  umami_db:

.env:

APP_SECRET=$(openssl rand -hex 32)
DB_PASSWORD=$(openssl rand -hex 24)

가동:

cd /home/user/umami
docker compose up -d
curl -I http://localhost:3001  # HTTP/1.1 200

기본 로그인: admin / umami. 즉시 비밀번호 변경.


4. 별고래 등록 + 트래커 받기

Umami 대시보드 → Websites → Add Website:

필드 값
Name 별고래 항해일지
Domain sticknstone.org

Save → 사이트 클릭 → Edit → Tracking Code:

<script defer src="https://analytics.sticknstone.org/script.js" data-website-id="1892c870-dd4d-4ce7-9fd6-2635f8ef6220"></script>

5. WP에 자동 주입 — mu-plugin

매 글마다 주인장이 코드 박는 게 아니라 자동.

/var/www/html/wp-content/mu-plugins/umami-tracker.php:

<?php
/**
 * Plugin Name: Umami Analytics Tracker
 * Description: Injects Umami tracker into front-end pages. Excludes logged-in users.
 */
if (!defined('ABSPATH')) exit;

add_action('wp_head', function () {
    if (is_admin()) return;
    if (is_user_logged_in()) return;  // 주인장 본인 방문은 제외
    ?>
    <script defer src="https://analytics.sticknstone.org/script.js" data-website-id="1892c870-dd4d-4ce7-9fd6-2635f8ef6220"></script>
    <?php
}, 100);

is_user_logged_in() 체크 = 주인장이 자기 글 미리보기 한 횟수가 통계에 안 잡힘. 의외로 중요.


6. 대시보드에서 보이는 것

화면 데이터
Overview 일·주·월별 방문자·페이지뷰·세션·체류 시간
Pages 인기 글 순위
Referrers 유입 경로 (구글·트위터·다른 사이트)
Browsers 크롬·사파리·파이어폭스 비율
OS 윈도우·맥·iOS·안드로이드
Devices 데스크탑·모바일·태블릿
Countries 국가별 방문자
Languages 브라우저 언어
Events 주인장이 정의한 클릭·다운로드 추적

5초마다 자동 갱신. Realtime 메뉴 = 지금 이 순간 누가 어느 페이지 보고 있나.


7. 도메인 연결과 함께 처리해야 하는 이유

처음 트래커 받으면 URL이 http://192.168.0.x:3001/script.js (LAN IP). 이건:
– HTTP → 브라우저 Mixed Content 차단
– LAN IP → 외부 방문자 PC에서 해석 불가

→ Umami는 도메인 연결(9편) 후에 활성화. analytics.sticknstone.org로 외부 노출돼야 작동.


FAQ

Q. Umami 무료 클라우드 플랜은?
Umami Cloud는 월 $9~. self-hosted는 무제한 무료. 미니PC 있으면 self-hosted가 답.

Q. Google Analytics에서 마이그레이션 가능?
과거 데이터 import 없음. 새 시작. 단 두 도구 동시 가동도 가능 (트래커 둘 다 박음).

Q. 한국 PIPA(개인정보보호법) 신경 써야 하나?
Umami는 IP 주소를 저장하지 않음 (해시만), 쿠키 없음. PIPA 면제 대상.

Q. 모바일 앱은?
공식 앱 없음. 모바일 웹은 반응형이라 폰에서도 잘 보임.

Q. 데이터를 CSV로 추출 가능?
대시보드에서 CSV·JSON export. API도 제공.


다음 편 예고

6편 — 도메인 사기: Cloudflare Registrar. 가비아·후이즈 두고 Cloudflare에서 산 이유 (가격·관리 통합·향후 Tunnel 연결).


한 줄 정리

Google Analytics의 진짜 비용은 사용자 데이터 외부화. Umami self-hosted = 미니PC에 5분 Docker + WP mu-plugin 자동 주입 = 데이터 주권 + 쿠키 없음 + 같은 정보.

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다