add goatcounter tracking to all sites via nginx sub_filter
Deploy nginx / deploy (push) Successful in 4s
Deploy nginx / deploy (push) Successful in 4s
This commit is contained in:
@@ -133,6 +133,19 @@ If any secret is missing, deploy fails with an error (not a warning).
|
||||
- **One domain per conf file** — `deploy.sh` derives the cert name from the
|
||||
filename and collects all `server_name` values for that cert
|
||||
|
||||
## GoatCounter (analytics)
|
||||
|
||||
GoatCounter runs at `goatcounter.hantim.net` for privacy-friendly web analytics.
|
||||
|
||||
**Script injection:** nginx injects the GoatCounter tracking script into all
|
||||
HTML responses via `sub_filter`. The shared include `conf.d/goatcounter.inc`
|
||||
is added to each site's main HTTPS server block. New sites get it automatically
|
||||
via `app.sh`.
|
||||
|
||||
**Config:** `docker/goatcounter/compose.yaml` uses the `baethon/goatcounter`
|
||||
image. Password is stored in Bitwarden (`hantim-goatcounter-password`) and
|
||||
injected via the `.env.keys` mechanism.
|
||||
|
||||
## URL routing
|
||||
|
||||
- All HTTP → HTTPS redirect
|
||||
|
||||
@@ -13,6 +13,7 @@ for technical deep-dives, USECASES.md for expected behaviors.
|
||||
- `tools/remove-app.sh` -- Remove a static site (local files + Gitea repo)
|
||||
- `docker/nginx/conf.d/` -- Per-app nginx server blocks
|
||||
- `docker/<domain>/compose.yml` -- Per-app compose files
|
||||
- `docker/goatcounter/` -- GoatCounter analytics (compose.yaml, .env.keys)
|
||||
- `docker/garage/` -- Garage S3 object storage (Dockerfile, garage.toml, .env.keys)
|
||||
- `.gitea/workflows/` -- Per-app deploy workflows + provision.yml
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ docker/
|
||||
compose.yml
|
||||
<domain>/ # Per-app compose files (e.g. example.com)
|
||||
compose.yml
|
||||
goatcounter/ # GoatCounter analytics
|
||||
garage/ # Garage S3-compatible object storage
|
||||
compose.yml
|
||||
Dockerfile
|
||||
@@ -195,6 +196,7 @@ Project: `hantim`. Fetched via `bws` CLI on the server.
|
||||
| `hantim-garage-media-key-id` | S3 access key ID for media uploads | `app.sh`, `aws` CLI |
|
||||
| `hantim-garage-media-secret-key` | S3 secret key for media uploads | `aws` CLI |
|
||||
| `hantim-uptimerobot-api-key` | UptimeRobot API key for monitors | `app.sh` |
|
||||
| `hantim-goatcounter-password` | GoatCounter admin password | `deploy.sh` |
|
||||
|
||||
Machine accounts: `hantim-server` (token at `/etc/bws-token`), `hantim-ci` (reserved).
|
||||
|
||||
|
||||
+12
-2
@@ -102,7 +102,17 @@ for stateless static sites.
|
||||
- SSL cert issued for `<name>.hantim.net` (no www variant)
|
||||
- Service ready for customization (edit compose.yml image, add `.env.keys` if needed)
|
||||
|
||||
## 9. Upload media files
|
||||
## 9. Analytics tracking
|
||||
|
||||
**Trigger:** automatic — nginx injects the GoatCounter script into all HTML responses.
|
||||
|
||||
**Expected outcome:**
|
||||
- Every site includes the GoatCounter tracking script (injected via `sub_filter`)
|
||||
- Page views are recorded at `goatcounter.hantim.net`
|
||||
- New sites provisioned with `app.sh` include tracking automatically
|
||||
- GoatCounter dashboard itself is not tracked
|
||||
|
||||
## 10. Upload media files
|
||||
|
||||
**Trigger:** `aws s3 cp` or `aws s3 sync` to `s3://example.com/`, or `./media.sh push` from a site repo.
|
||||
|
||||
@@ -111,7 +121,7 @@ for stateless static sites.
|
||||
- Replicated to both Garage nodes (hantim + argento)
|
||||
- Accessible at `https://www.example.com/media/<path>`
|
||||
|
||||
## 10. Local development with media files
|
||||
## 11. Local development with media files
|
||||
|
||||
**Trigger:** `./media.sh pull` from a site repo.
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
sub_filter '</body>' '<script data-goatcounter="https://goatcounter.hantim.net/count" async src="//goatcounter.hantim.net/count.js"></script></body>';
|
||||
sub_filter_once on;
|
||||
sub_filter_types text/html;
|
||||
@@ -37,6 +37,7 @@ server {
|
||||
ssl_certificate_key /etc/letsencrypt/live/haanmind.net/privkey.pem;
|
||||
|
||||
include /etc/nginx/conf.d/security-headers.inc;
|
||||
include /etc/nginx/conf.d/goatcounter.inc;
|
||||
|
||||
location /media/ {
|
||||
proxy_pass http://garage:3902/;
|
||||
|
||||
@@ -37,6 +37,7 @@ server {
|
||||
ssl_certificate_key /etc/letsencrypt/live/hantim.net/privkey.pem;
|
||||
|
||||
include /etc/nginx/conf.d/security-headers.inc;
|
||||
include /etc/nginx/conf.d/goatcounter.inc;
|
||||
|
||||
location /media/ {
|
||||
proxy_pass http://garage:3902/;
|
||||
|
||||
@@ -37,6 +37,7 @@ server {
|
||||
ssl_certificate_key /etc/letsencrypt/live/hcsuzuki.music/privkey.pem;
|
||||
|
||||
include /etc/nginx/conf.d/security-headers.inc;
|
||||
include /etc/nginx/conf.d/goatcounter.inc;
|
||||
|
||||
location /media/ {
|
||||
proxy_pass http://garage:3902/;
|
||||
|
||||
@@ -37,6 +37,7 @@ server {
|
||||
ssl_certificate_key /etc/letsencrypt/live/hcsuzuki.net/privkey.pem;
|
||||
|
||||
include /etc/nginx/conf.d/security-headers.inc;
|
||||
include /etc/nginx/conf.d/goatcounter.inc;
|
||||
|
||||
location /media/ {
|
||||
proxy_pass http://garage:3902/;
|
||||
|
||||
@@ -37,6 +37,7 @@ server {
|
||||
ssl_certificate_key /etc/letsencrypt/live/thekims.family/privkey.pem;
|
||||
|
||||
include /etc/nginx/conf.d/security-headers.inc;
|
||||
include /etc/nginx/conf.d/goatcounter.inc;
|
||||
|
||||
location /media/ {
|
||||
proxy_pass http://garage:3902/;
|
||||
|
||||
@@ -37,6 +37,7 @@ server {
|
||||
ssl_certificate_key /etc/letsencrypt/live/timothykim.net/privkey.pem;
|
||||
|
||||
include /etc/nginx/conf.d/security-headers.inc;
|
||||
include /etc/nginx/conf.d/goatcounter.inc;
|
||||
|
||||
location /media/ {
|
||||
proxy_pass http://garage:3902/;
|
||||
|
||||
@@ -356,6 +356,7 @@ server {
|
||||
ssl_certificate_key /etc/letsencrypt/live/$APP/privkey.pem;
|
||||
|
||||
include /etc/nginx/conf.d/security-headers.inc;
|
||||
include /etc/nginx/conf.d/goatcounter.inc;
|
||||
|
||||
location /media/ {
|
||||
proxy_pass http://garage:3902/;
|
||||
|
||||
Reference in New Issue
Block a user