Tag: Star Whale 구축기

  • Star Whale Analytics Lab — Visitor Statistics with Umami

    Star Whale Analytics Lab — Visitor Statistics with Umami

    Star Whale Analytics Lab — Visitor Statistics with Umami

    Self-hosting build series part 5. Taking data sovereignty to the mini-PC.


    TL;DR

    • Google Analytics free = I give visitor data to Google servers + forced cookie consent pop-ups
    • Umami self-hosted = own analysis on mini-PC. No cookies, data owned by me, automatic exemption from GDPR
    • Docker Compose in 5 minutes. Automatic injection of one line tracker into WP = done
    • Display: visitor count, popular posts, traffic sources, devices, countries, dwell time

    1. The Hidden Costs of Google Analytics

    Item Google Analytics 4 Umami self-hosted
    Cost Free (personal use) Free (open source)
    Data Ownership Google Own mini-PC
    Cookie Consent Popup Required (GDPR/CCPA) Unnecessary (0 cookies)
    Page Load Load ~50KB JS ~2KB JS
    User Tracking Cross-site (linked to Google ads) Same site only
    South Korea PIPA Compliance Complicated Automatic exemption
    Setup Complexity 1 hour+ 5 minutes

    Google Analytics externalizes the real costs to the user (the visitor). Is it normal for Google to take all that data just because a visitor entered my site? For a personal blog, it is right to operate it ourselves.


    2. Structure

    

    When the visitor browser receives the Star Whale page, the script in the head <script defer src="https://analytics.sticknstone.org/script.js" data-website-id="..."> executes → asynchronous request to Umami → Umami logs to Postgres. The page display is not interrupted.


    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)
    

    Run:

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

    Default login: admin / umami. Change the password immediately.


    4. Registering Star Whale + Receiving Tracker

    Umami dashboard → Websites → Add Website:

    Field Value
    Name Star Whale Logbook
    Domain sticknstone.org

    Save → Click site → Edit → Tracking Code:

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

    5. Automatic Injection into WP — mu-plugin

    The code is automatically placed, not manually by me for every post.

    /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;  // Exclude my own visits
        ?>
        <script defer src="https://analytics.sticknstone.org/script.js" data-website-id="1892c870-dd4d-4ce7-9fd6-2635f8ef6220"></script>
        <?php
    }, 100);
    

    Checking is_user_logged_in() = the number of times I’ve previewed my own posts will not be counted in the statistics. Surprisingly important.


    6. What is Visible on the Dashboard

    Screen Data
    Overview Daily, weekly, monthly visitors, page views, sessions, dwell time
    Pages Ranking of popular posts
    Referrers Traffic sources (Google, Twitter, other sites)
    Browsers Chrome, Safari, Firefox ratio
    OS Windows, Mac, iOS, Android
    Devices Desktop, mobile, tablet
    Countries Visitors by country
    Languages Browser languages
    Events Clicks and downloads defined by me

    Automatically updates every 5 seconds. Realtime menu = see who is currently viewing which page.


    7. Reason to Handle Domain Linking Together

    When the tracker is first received, the URL is http://192.168.0.x:3001/script.js (LAN IP). This causes:
    – HTTP → Browser Mixed Content block
    – LAN IP → Uninterpretable from external visitor PCs

    Umami must be activated after connecting the domain (part 9). It needs to be exposed externally as analytics.sticknstone.org to function.


    FAQ

    Q. Is there a free cloud plan for Umami?
    Umami Cloud starts at $9 per month. Self-hosted is unlimited and free. If you have a mini-PC, self-hosted is the answer.

    Q. Can I migrate from Google Analytics?
    No past data import. It’s a fresh start. However, both tools can be operational concurrently (both trackers can be placed).

    Q. Do I need to worry about South Korea’s PIPA (Personal Information Protection Act)?
    Umami does not store IP addresses (only hashes), and there are no cookies. It qualifies for PIPA exemption.

    Q. Is there a mobile app?
    No official app. The mobile web is responsive, so it displays well on phones.

    Q. Can I export data as CSV?
    CSV and JSON export are available on the dashboard. API is also provided.


    Next Part Preview

    Part 6 — Domain Fraud: Cloudflare Registrar. Reasons for purchasing from Cloudflare with Gabia and WhoIs (price, management integration, future Tunnel connection).


    Summary in One Line

    The real cost of Google Analytics is the externalization of user data. Umami self-hosted = 5 minutes of Docker on the mini-PC + automatic WP mu-plugin injection = data sovereignty + no cookies + the same information.