Ghost 블로그 Analytics 설정 완벽 가이드 - Tinybird로 트래픽 분석하기
Ghost 셀프호스팅 블로그에 Tinybird Analytics를 설정하여 트래픽을 분석하는 방법을 단계별로 설명합니다.
1. Ghost Analytics 개요
Ghost 6.0부터 Tinybird 기반의 Analytics 기능이 도입되었습니다. Ghost(Pro)에서는 자동으로 활성화되지만, 셀프호스팅 환경에서는 추가 설정이 필요합니다.
1.1 Tinybird란?
Tinybird는 실시간 분석 플랫폼으로, Ghost의 트래픽 데이터를 수집하고 분석합니다.
Tinybird Analytics 제공 정보:
├── 페이지뷰 (일별/주별/월별)
├── 방문자 수 (유니크)
├── 인기 포스트
├── 트래픽 소스 (referrer)
├── 디바이스/브라우저 통계
└── 지역별 방문자
1.2 GDPR 컴플라이언스란?
**GDPR(General Data Protection Regulation)**은 EU의 개인정보보호 규정입니다.
GDPR 핵심 요구사항:
├── 데이터 최소화: 필요한 데이터만 수집
├── 목적 제한: 명시된 목적으로만 사용
├── 저장 제한: EU 역내 또는 적정성 결정 국가에 저장
├── 동의 확보: 사용자 동의 필수 (쿠키 배너 등)
└── 삭제권: 사용자 요청 시 데이터 삭제
Tinybird EU 리전 선택 시 이점:
- 데이터가 EU 데이터센터(europe-west2, 런던)에 저장
- EU 방문자 데이터의 역외 이전 없음
- GDPR 컴플라이언스 충족 용이
참고: Tinybird Analytics는 쿠키를 사용하지 않는 cookie-free 분석입니다. 그러나 IP 주소 등 개인정보 수집 시 쿠키 동의 배너와 별개로 개인정보처리방침 고지가 필요할 수 있습니다.
1.3 Ghost Pro vs 셀프호스팅
| 항목 | Ghost Pro | 셀프호스팅 |
|---|---|---|
| 설정 | 자동 | 수동 설정 필요 |
| 비용 | Ghost Pro 요금 포함 | Tinybird Free Tier |
| 데이터 저장 | Ghost 관리 | Tinybird 워크스페이스 |
| 이벤트 제한 | 무제한 | Free: 100GB 처리량/월 |
1.4 아키텍처
[사용자 브라우저]
│
│ 페이지 로드
▼
[Ghost 블로그]
│
│ Analytics 스크립트 로드
│ (/.ghost/analytics)
▼
[Traffic Proxy] ← Docker 컨테이너
│
│ 이벤트 전송
▼
[Tinybird API]
│
▼
[Ghost Admin Dashboard]
2. 사전 준비
2.1 필수 조건
- Ghost 6.0 이상
- Tinybird 계정 (무료 가입 가능)
- Docker 환경 (Traffic Proxy 실행용)
- Nginx Proxy Manager (프록시 설정용)
2.2 작업 개요
설정 순서:
1. Tinybird 계정 생성 및 워크스페이스 설정
2. Ghost TrafficAnalytics 스키마 배포
3. Traffic Proxy 컨테이너 설정
4. NPM 프록시 경로 추가
5. Ghost 환경변수 설정
6. 테스트 및 확인
3. Tinybird 계정 설정
3.1 계정 생성
- Tinybird 접속
- Start for free 클릭
- GitHub 또는 이메일로 가입
- 워크스페이스 리전 선택 (EU 또는 US)
팁: EU 리전(europe-west2)을 선택하면 GDPR 컴플라이언스에 유리합니다.
3.2 API 토큰 확인
- Tinybird Dashboard 접속
- Tokens 메뉴 클릭
- 다음 토큰 확인/생성:
| 토큰 | 용도 | 권한 |
|---|---|---|
| Admin Token | CLI 배포용 | 전체 권한 |
| Tracker Token | 이벤트 전송용 | DATASOURCE:APPEND |
3.3 리전별 API 엔드포인트
| 리전 | API 엔드포인트 |
|---|---|
| EU (europe-west2) | https://api.europe-west2.gcp.tinybird.co |
| US (us-east-1) | https://api.us-east.tinybird.co |
4. TrafficAnalytics 스키마 배포
Ghost의 TrafficAnalytics 스키마를 Tinybird에 배포해야 합니다.
중요: SSH 환경에서는 브라우저 인증이 불가능하므로, 로컬 PC에서 CLI를 설치하고 스키마를 배포합니다.
4.1 로컬에서 Tinybird CLI 설치
# 로컬 PC (Mac/Linux)에서 실행
curl https://tinybird.co | sh
# PATH 설정
export PATH="$HOME/.local/bin:$PATH"
# 설치 확인
tb --version
4.2 Tinybird 로그인
# EU 리전으로 로그인
tb login --host https://api.europe-west2.gcp.tinybird.co
# 브라우저가 열리면 인증 완료
# 워크스페이스 선택
4.3 Ghost 공식 템플릿으로 스키마 배포
# Ghost TrafficAnalytics 템플릿 배포
tb --cloud deploy --template https://github.com/TryGhost/Ghost/tree/main/ghost/core/core/server/data/tinybird
# 성공 메시지 확인
# ✓ Deployment is ready
# ✓ Deployment promoted
# ✓ Deployment #1 is live!
4.4 워크스페이스 정보 확인
tb --cloud info
# workspace_id, api URL 등 확인
tb --cloud token ls
# workspace admin token, tracker 토큰 확인
4.5 배포 확인
Tinybird Dashboard에서 확인:
- Data Sources:
analytics_events,_mv_hits,_mv_session_data_v2 - Endpoints:
api_top_pages,api_top_sources,api_kpis등 - Tokens:
tracker,stats_page,axis,monitoring
5. Traffic Proxy 설정
Traffic Proxy는 브라우저에서 보낸 Analytics 이벤트를 Tinybird API로 전달하는 프록시 서버입니다.
참고: Ghost 공식 Docker 이미지
ghost/traffic-analytics를 사용합니다. 별도 빌드 불필요.
5.1 필요한 정보 확인
Tinybird Dashboard에서 다음 정보를 확인하세요:
| 항목 | 위치 | 예시 |
|---|---|---|
| Workspace ID | Settings | d757a313-5a70-4cb9-87ce-fc0be7689f5c |
| Admin Token | Tokens → workspace admin token | p.eyJ1... |
| Tracker Token | Tokens → tracker | p.eyJ1... |
| API URL | 리전별 | https://api.europe-west2.gcp.tinybird.co |
5.2 docker-compose.yml 수정
~/docker/ghost/docker-compose.yml 전체 설정:
services:
ghost:
image: ghost:6-alpine
container_name: ghost
restart: unless-stopped
ports:
- "2368:2368"
environment:
url: https://blog.example.com
database__client: mysql
database__connection__host: ghost-db
database__connection__user: ghost
database__connection__password: ${GHOST_DB_PASSWORD}
database__connection__database: ghost
# Tinybird Analytics 설정 (Ghost 형식 - 더블 언더스코어)
tinybird__tracker__endpoint: https://blog.example.com/.ghost/analytics/api/v1/page_hit
tinybird__tracker__datasource: analytics_events
tinybird__adminToken: ${TINYBIRD_ADMIN_TOKEN}
tinybird__workspaceId: ${TINYBIRD_WORKSPACE_ID}
tinybird__stats__endpoint: ${TINYBIRD_API_URL}
volumes:
- ghost-content:/var/lib/ghost/content
depends_on:
- ghost-db
networks:
- ghost-network
ghost-db:
image: mysql:8.0
container_name: ghost-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ghost
MYSQL_USER: ghost
MYSQL_PASSWORD: ${GHOST_DB_PASSWORD}
volumes:
- ghost-db-data:/var/lib/mysql
networks:
- ghost-network
# Traffic Analytics Proxy (공식 이미지)
traffic-analytics:
image: ghost/traffic-analytics:1.0.39
container_name: ghost-traffic-analytics
restart: unless-stopped
ports:
- "3000:3000"
environment:
NODE_ENV: production
PROXY_TARGET: ${TINYBIRD_API_URL}/v0/events
SALT_STORE_TYPE: file
SALT_STORE_FILE_PATH: /data/salts.json
TINYBIRD_TRACKER_TOKEN: ${TINYBIRD_TRACKER_TOKEN}
LOG_LEVEL: info
volumes:
- traffic-analytics-data:/data
networks:
- ghost-network
volumes:
ghost-content:
ghost-db-data:
traffic-analytics-data:
networks:
ghost-network:
driver: bridge
5.3 환경변수 파일 생성
cat > ~/docker/ghost/.env << 'EOF'
GHOST_DB_PASSWORD=your_ghost_db_password
MYSQL_ROOT_PASSWORD=your_mysql_root_password
TINYBIRD_API_URL=https://api.europe-west2.gcp.tinybird.co
TINYBIRD_ADMIN_TOKEN=p.your_admin_token
TINYBIRD_WORKSPACE_ID=your_workspace_id
TINYBIRD_TRACKER_TOKEN=p.your_tracker_token
EOF
# 권한 설정
chmod 600 ~/docker/ghost/.env
5.4 컨테이너 실행
cd ~/docker/ghost
docker compose pull traffic-analytics
docker compose up -d
5.5 실행 확인
docker ps --format 'table {{.Names}}\t{{.Status}}'
# ghost-traffic-analytics Up X minutes
# ghost Up X minutes
# ghost-db Up X minutes
# 로그 확인
docker logs ghost-traffic-analytics --tail 20
# Server listening at http://...
6. Nginx Proxy Manager 설정
NPM에서 Analytics 경로를 Traffic Proxy로 라우팅해야 합니다.
6.1 NPM Advanced 탭 설정
blog.example.com 호스트 → Edit → Advanced 탭:
기존 ActivityPub 설정 아래에 추가:
# ActivityPub 설정 (기존)
location /.ghost/activitypub {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_ssl_server_name on;
proxy_pass https://ap.ghost.org;
}
# ... (webfinger, nodeinfo 설정) ...
# Analytics Proxy (새로 추가)
location /.ghost/analytics/ {
proxy_pass http://172.17.0.1:3000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host;
}
6.2 설정 저장
Save 클릭
7. Cloudflare Cache Rules 업데이트
Analytics 경로도 캐시에서 제외해야 합니다.
7.1 기존 Cache Rule 수정
Cloudflare Dashboard → Rules → Cache Rules
기존 "Ghost ActivityPub Bypass" 규칙 수정:
When incoming requests match...
| Field | Operator | Value |
|---|---|---|
| URI Path | starts with | /.ghost/activitypub |
| Or | ||
| URI Path | starts with | /.well-known/webfinger |
| Or | ||
| URI Path | starts with | /.well-known/nodeinfo |
| Or | ||
| URI Path | starts with | /.ghost/analytics |
Then... → Bypass cache
7.2 규칙 저장
Save 클릭
8. Ghost 재시작 및 확인
8.1 컨테이너 재시작
cd ~/docker/ghost
docker compose down
docker compose up -d
8.2 로그 확인
# Ghost 로그
docker logs ghost --tail 30
# Traffic Proxy 로그
docker logs ghost-traffic-analytics --tail 30
8.3 Analytics 엔드포인트 테스트
# Analytics 경로 확인
curl -s https://blog.example.com/.ghost/analytics/health
# {"status":"ok"}
9. Ghost Admin에서 확인
9.1 Dashboard 확인
- Ghost Admin 접속:
https://blog.example.com/ghost - Dashboard 클릭
- 트래픽 그래프 및 통계 확인
9.2 데이터 수집 시작
- 페이지뷰 데이터는 실시간으로 수집됩니다
- 첫 데이터가 표시되기까지 수 분 ~ 수 시간 소요될 수 있습니다
9.3 Tinybird Dashboard 확인
Tinybird Dashboard에서도 직접 데이터 확인 가능:
- Data Sources →
analytics_events - 최근 이벤트 확인
10. 트러블슈팅
10.1 Analytics 데이터가 표시되지 않음
원인: Traffic Proxy 연결 문제
# Traffic Proxy 상태 확인
docker ps | grep traffic-proxy
# 프록시 로그 확인
docker logs ghost-traffic-analytics --tail 50
10.2 CORS 에러
원인: NPM 설정 누락
해결:
- NPM Advanced 설정 확인
- location 블록에 CORS 헤더 추가:
location /.ghost/analytics {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
# ... 기존 설정 ...
}
10.3 Tinybird 인증 에러
원인: 토큰 문제
# 환경변수 확인
docker exec ghost-traffic-analytics env | grep TINYBIRD
# 토큰 형식 확인 (p. 접두사 필요)
# TINYBIRD_TRACKER_TOKEN=p.xxxxx
10.4 Ghost에서 Analytics 스크립트 미로드
원인: Ghost 환경변수 미설정 또는 형식 오류
해결:
docker-compose.yml의 Ghost 서비스에 올바른 형식의 환경변수 추가:
environment:
# 더블 언더스코어(__) 형식 사용
tinybird__tracker__endpoint: https://blog.example.com/.ghost/analytics/api/v1/page_hit # ← 전체 경로 필수
tinybird__tracker__datasource: analytics_events
tinybird__adminToken: ${TINYBIRD_ADMIN_TOKEN}
tinybird__workspaceId: ${TINYBIRD_WORKSPACE_ID}
tinybird__stats__endpoint: ${TINYBIRD_API_URL}
주의:
TINYBIRD_API_URL같은 대문자 형식은 Ghost가 인식하지 못합니다. 반드시tinybird__형식을 사용하세요.
10.5 HTTP 404 에러: Analytics 이벤트 전송 실패
증상:
POST /.ghost/analytics?name=analytics_events 404
# NPM 로그:
the rewritten URI has a zero length
원인:
NPM 프록시 설정에서 잘못된 rewrite 규칙 사용
해결:
NPM Advanced 설정에서 location 경로 수정:
# ❌ 잘못된 설정 (zero length URI 발생)
location /.ghost/analytics {
rewrite ^/.ghost/analytics(.*)$ $1 break; # ← rewrite 제거 필요
proxy_pass http://172.17.0.1:3000;
}
# ✅ 올바른 설정
location /.ghost/analytics/ { # ← 끝에 / 추가 필수
proxy_pass http://172.17.0.1:3000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host;
}
핵심:
location끝에/추가:/.ghost/analytics/proxy_pass끝에/추가:http://172.17.0.1:3000/rewrite규칙 제거
이렇게 하면 /.ghost/analytics/api/v1/page_hit → http://172.17.0.1:3000/api/v1/page_hit로 올바르게 전달됩니다.
10.6 Tinybird Quarantine: 데이터 스키마 불일치
증상:
- Tinybird quarantine에 데이터가 쌓임
- 에러 메시지:
Strict type checking failed. Object does not have column 'site_uuid',
you should send a value or recreate the table with a Nullable column type.
While accessing jsonpath '$.payload.site_uuid'
원인:
섹션 4.3의 Ghost 공식 템플릿 배포를 건너뛰고 수동으로 스키마를 생성했거나, 잘못된 템플릿을 사용한 경우
중요: 섹션 4.3에서
tb --cloud deploy --template https://github.com/TryGhost/Ghost/...명령으로 올바르게 배포했다면 이 문제는 발생하지 않습니다.
해결 방법 1: 새 워크스페이스 생성 (권장)
-
기존 워크스페이스 삭제 (선택사항):
- Tinybird Dashboard 접속
- 좌측 하단 설정 클릭
- General → Danger Zone → Delete workspace
delete workspace입력 후 삭제
-
새 워크스페이스 생성 및 배포:
- Tinybird Dashboard → 좌측 상단 드롭다운 → Create workspace
- 이름:
ghost_blog_yoursite(예시) - 리전: EU (europe-west2)
- 생성 후 섹션 4.3의 템플릿 배포 명령 다시 실행
-
Ghost 설정 업데이트:
# 새 워크스페이스 정보 확인 tb --cloud info tb --cloud token ls # docker-compose.yml 업데이트 # - tinybird__workspaceId: [새 Workspace ID] # - tinybird__adminToken: [새 Admin Token] # - TINYBIRD_TRACKER_TOKEN: [새 Tracker Token] # Ghost 재시작 cd ~/docker/ghost docker compose down && docker compose up -d
해결 방법 2: 기존 워크스페이스 초기화
기존 워크스페이스를 유지하려면 모든 데이터소스와 파이프를 수동으로 삭제 후 템플릿 재배포 (복잡하고 오류 가능성 높음, 비권장)
10.7 엔드포인트 경로 누락: HTTP 404 → 202
증상:
- Traffic Analytics에 요청은 도달하지만 404 반환
- NPM 설정은 올바른데도 작동하지 않음
원인:
Ghost 환경변수에 전체 엔드포인트 경로 누락
해결:
docker-compose.yml의 Ghost 환경변수 수정:
# ❌ 잘못된 설정
tinybird__tracker__endpoint: https://blog.example.com/.ghost/analytics
# ✅ 올바른 설정
tinybird__tracker__endpoint: https://blog.example.com/.ghost/analytics/api/v1/page_hit
확인:
# 페이지 HTML에서 analytics 스크립트 확인
curl -s https://blog.example.com/ | grep "data-host"
# 출력: data-host="https://blog.example.com/.ghost/analytics/api/v1/page_hit"
10.8 설정 검증 방법
1. Traffic Analytics 로그 확인:
docker logs ghost-traffic-analytics --tail 20
# status 202가 나오면 성공
성공 로그 예시:
{
"event": "RequestCompleted",
"httpRequest": {
"requestMethod": "POST",
"requestUrl": "/api/v1/page_hit?name=analytics_events",
"status": 202, // ← 성공
"latency": "0.257s"
}
}
2. Tinybird 데이터 확인:
- Tinybird Dashboard → Data Sources →
analytics_events - 최근 이벤트 확인 (몇 분 후 데이터 표시)
3. Ghost Admin 확인:
- https://blog.example.com/ghost → Dashboard
- 트래픽 그래프 표시 확인 (데이터 수집 후 몇 분 소요)
4. 실시간 테스트:
# 모바일/다른 PC로 블로그 방문
# 그 직후 로그 확인
docker logs ghost-traffic-analytics --since 1m | grep "status\":202"
11. 핵심 개념 정리
| 개념 | 설명 |
|---|---|
| Tinybird | 실시간 분석 플랫폼, Ghost Analytics 백엔드 |
| Traffic Proxy | 브라우저 → Tinybird 이벤트 전달 프록시 |
| Tracker Token | Tinybird 이벤트 전송용 인증 토큰 |
| Analytics Events | 페이지뷰, 클릭 등 사용자 행동 데이터 |
12. 베스트 프랙티스
체크리스트
- [ ] Tinybird 계정 생성 및 워크스페이스 설정
- [ ] TrafficAnalytics 스키마 배포
- [ ] Traffic Proxy 컨테이너 실행
- [ ] NPM Analytics 경로 프록시 설정
- [ ] Cloudflare Cache Rules 업데이트
- [ ] Ghost 환경변수 설정
- [ ] Ghost Admin Dashboard 확인
데이터 보존 정책
| Tinybird Tier | 데이터 보존 |
|---|---|
| Free | 처리량 100GB/월 |
| Pro | 무제한 |
13. FAQ
Q: Tinybird Free Tier로 충분한가요?
A: 대부분의 개인 블로그에 충분합니다. 월 100GB 처리량이면 수십만 페이지뷰를 처리할 수 있습니다.
Q: Google Analytics와 함께 사용할 수 있나요?
A: 네, 둘 다 사용 가능합니다. Ghost는 Tinybird를 기본 Analytics로 사용하고, GA는 Code Injection으로 추가할 수 있습니다.
Q: ARM64 서버에서 Traffic Proxy가 작동하나요?
A: Node.js 기반이므로 ARM64에서도 정상 작동합니다.
Q: 기존 Analytics 데이터를 마이그레이션할 수 있나요?
A: 아니요, Tinybird Analytics는 설정 시점부터 새로 데이터를 수집합니다.
Q: GDPR 컴플라이언스는 어떻게 되나요?
A: Tinybird EU 리전을 사용하면 데이터가 EU 내에 저장됩니다. Tinybird는 cookie-free 분석이지만, 개인정보처리방침 고지는 별도로 필요합니다.
Q: Tinybird Dashboard의 flock.js 스크립트를 Ghost에 추가해야 하나요?
A: 아니요, Ghost에서는 필요 없습니다. Tinybird Quick Setup에 나오는 flock.js 스크립트는 일반 웹사이트용입니다. Ghost는 자체적으로 ghost-stats.min.js를 로드하고 Traffic Proxy를 통해 Tinybird로 데이터를 전송합니다. Ghost 환경변수 설정만 하면 됩니다.
14. 시리즈 완료
축하합니다! 7편의 시리즈를 모두 완료했습니다.
시리즈 목차:
- Oracle Cloud 무료 서버 세팅
- Ghost 블로그 Docker 설치
- Ghost 블로그 백업 자동화
- 검색엔진 등록 (Google/Naver)
- Ghost 6.0 업그레이드
- Ghost ActivityPub 설정 (Fediverse)
- Ghost Analytics 설정 (Tinybird) ← 현재 글
완성된 인프라 (최종)
[Oracle Cloud - 무료]
├── 4 OCPU, 24GB RAM, 200GB
├── Ubuntu 24.04 + Docker
├── UFW + fail2ban (보안)
│
├── [Nginx Proxy Manager]
│ └── Cloudflare Origin CA (SSL)
│
├── [Ghost 6.0]
│ ├── MySQL 8.0
│ ├── ActivityPub (Fediverse 연결)
│ └── Tinybird Analytics
│
├── [Traffic Proxy]
│ └── Tinybird 이벤트 전달
│
└── [백업 자동화]
├── 서버 로컬 (7일)
└── GitHub Private (최신 1개)
[Cloudflare]
├── DNS + CDN + DDoS 방어
└── SSL/TLS: Full (Strict)
[검색엔진]
├── Google Search Console
└── Naver Search Advisor
[Analytics]
└── Tinybird (실시간 트래픽 분석)