--- title: Userdir traffic stats category: software Author: deepend --- So you want traffic stats for your `~/public_html` site, This stats system generates a **sanitized** report per user from the server’s nginx logs, then lets you publish it *only if you choose to*. ## What this gives you * Daily totals: requests, pageviews, unique visitors (hashed per-day), bytes * “Top pages” list (query strings removed) * Referrers by **domain only** (no full URLs) * Browser/user-agent buckets (Chrome/Firefox/Bot/etc.) * HTTP status code counts * Optionally: a nice HTML dashboard generated by `goaccess` No raw IPs are shown in the report. ## Opt-in (required) Nothing is generated for you unless you opt in. Create the opt-in flag: ```sh mkdir -p ~/.config/tilde-stats touch ~/.config/tilde-stats/enabled ``` That’s it. The nightly job will include you from then on. ## Where the files are written Reports are generated into: * `~/.local/share/tilde-stats/index.html` * `~/.local/share/tilde-stats/stats.json` These files are **not automatically public**. ## Publishing the report on your website There are two ways to publish the report: * **Copy (recommended)**: keeps `~/.local` private and uses normal web permissions. * **Symlink (works, but requires permissions)**: points your website at `~/.local/...`, which means nginx must be able to traverse those dot-directories. Your stats page will be: * `https://tilde.club/~YOURNAME/stats/` ### Recommended: copy into `~/public_html/stats/` ```sh mkdir -p ~/public_html/stats cp -f ~/.local/share/tilde-stats/index.html ~/public_html/stats/index.html cp -f ~/.local/share/tilde-stats/stats.json ~/public_html/stats/stats.json chmod 644 ~/public_html/stats/index.html ~/public_html/stats/stats.json ``` ### Alternative: symlink into `~/public_html/stats/` (requires permissions) ```sh mkdir -p ~/public_html/stats ln -sf ~/.local/share/tilde-stats/index.html ~/public_html/stats/index.html ln -sf ~/.local/share/tilde-stats/stats.json ~/public_html/stats/stats.json ``` If you use symlinks, nginx must be able to **traverse** the real path under `~/.local/...` (see permissions below). ## Permissions (important, because Linux will happily sabotage you) For nginx to serve a file, it must be able to: * **traverse** every directory in the path (execute bit, `+x`) * **read** the file (`+r`) ### Minimum permissions for userdir websites If your `~/public_html` site already works, you probably already have this, but here’s the standard expectation: ```sh chmod 711 ~ ``` `chmod 711 ~` lets the web server traverse your home directory without listing it. ### If you are COPYING files (recommended) Make sure your published files are world-readable: ```sh chmod 644 ~/public_html/stats/index.html ~/public_html/stats/stats.json ``` Your `~/.local/share/tilde-stats/` directory can stay private. ### If you are SYMLINKING to `~/.local/share/tilde-stats/` (current reality) Because the report lives in a dot-directory path, nginx must be able to traverse: * `~` * `~/.local` * `~/.local/share` * `~/.local/share/tilde-stats` And it must be able to read the report files themselves. Use these permissions: ```sh chmod 711 ~/.local ~/.local/share ~/.local/share/tilde-stats chmod 644 ~/.local/share/tilde-stats/index.html ~/.local/share/tilde-stats/stats.json ``` Notes: * `711` is better than `755` for dot-directories since it allows traversal but not directory listing. * If the generator writes the files with private permissions, you may need to re-apply the `chmod 644` on the two report files after regeneration if you are serving them directly from `~/.local`. ## Updating / regenerating Stats are generated by an admin-run job (typically nightly). You don’t need to run anything manually. If you publish via **copy**, re-run the copy commands after the nightly update to refresh the public version. If you publish via **symlink**, the page updates automatically (as long as permissions allow nginx to read it). ## Disabling / opting out Remove the opt-in flag: ```sh rm -f ~/.config/tilde-stats/enabled ``` No new reports will be generated for you after that. (Any old published copies or symlinks you created are your responsibility to delete.) ## Troubleshooting ### “My stats page 403s / 404s” * Confirm the public files exist: ```sh ls -l ~/public_html/stats/ ``` * Confirm permissions all the way down the path: ```sh namei -l ~/public_html/stats/index.html ``` If you’re using symlinks into `~/.local`, also check the target path: ```sh namei -l ~/.local/share/tilde-stats/index.html ``` Every directory in that output should have `x` for others (traversable), and the file should have `r` for others. ### “The report exists in ~/.local/share but isn’t public” That’s expected. It’s private until you copy or link it into `~/public_html`. ### “My report is empty” Either: * No traffic in the selected window, or * You opted in recently and the next scheduled run hasn’t happened yet. (Servers do not read minds, only logs.)