Vince fixed
This commit is contained in:
@@ -8,10 +8,11 @@
|
|||||||
reverse_proxy {{ docker_container }}:{{ cms_port }}
|
reverse_proxy {{ docker_container }}:{{ cms_port }}
|
||||||
}
|
}
|
||||||
|
|
||||||
# First-party analytics (Vince) — script (/stats/js/script.js) and event
|
# First-party analytics (Vince) — the tracker script and event endpoint
|
||||||
# endpoint (/stats/api/event) proxied same-origin so they survive ad
|
# are proxied same-origin with the /stats prefix stripped (vince serves
|
||||||
# blockers and never touch a third-party domain.
|
# /js/script.js and /api/event), so they survive ad blockers and never
|
||||||
handle /stats/* {
|
# touch a third-party domain.
|
||||||
|
handle_path /stats/* {
|
||||||
reverse_proxy {{ vince_container }}:{{ vince_port }}
|
reverse_proxy {{ vince_container }}:{{ vince_port }}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,3 +26,10 @@
|
|||||||
redir / /_/
|
redir / /_/
|
||||||
reverse_proxy {{ docker_container }}:{{ cms_port }}
|
reverse_proxy {{ docker_container }}:{{ cms_port }}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Vince analytics dashboard (login-protected). DNS for this host must point
|
||||||
|
# at this server; the tracker script itself stays on the www host at
|
||||||
|
# /stats/* — this is only for humans reading the dashboard.
|
||||||
|
{{ stats_host }} {
|
||||||
|
reverse_proxy {{ vince_container }}:{{ vince_port }}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
# vince_container / vince_port live in ansible/vars/default.yml (the Caddy
|
# vince_container / vince_port / vince_admin_* / vince_site_domain /
|
||||||
# template needs them at play level).
|
# stats_host live in ansible/vars/default.yml (the Caddy template needs them
|
||||||
|
# at play level).
|
||||||
vince_image: ghcr.io/vinceanalytics/vince:latest
|
vince_image: ghcr.io/vinceanalytics/vince:latest
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
---
|
---
|
||||||
# Self-hosted first-party analytics (Vince — Plausible-protocol, single
|
# Self-hosted first-party analytics (Vince — Plausible-protocol, single
|
||||||
# binary). Only reachable on the docker network: Caddy proxies /stats/*
|
# binary). Only reachable on the docker network:
|
||||||
# on the www host to this container, so browser requests stay first-party.
|
# - Caddy proxies /stats/* on the www host here (prefix stripped), serving
|
||||||
|
# the tracker script and event API first-party;
|
||||||
|
# - Caddy publishes the dashboard on {{ stats_host }}.
|
||||||
|
#
|
||||||
|
# The image's ENTRYPOINT is the bare /vince binary (prints help and exits
|
||||||
|
# with no args), so the container MUST be given the `serve` command.
|
||||||
- name: Pull Vince image
|
- name: Pull Vince image
|
||||||
docker_image:
|
docker_image:
|
||||||
name: "{{ vince_image }}"
|
name: "{{ vince_image }}"
|
||||||
@@ -20,8 +25,19 @@
|
|||||||
docker_container:
|
docker_container:
|
||||||
name: "{{ vince_container }}"
|
name: "{{ vince_container }}"
|
||||||
image: "{{ vince_image }}"
|
image: "{{ vince_image }}"
|
||||||
|
command: serve
|
||||||
state: started
|
state: started
|
||||||
restart_policy: "unless-stopped"
|
restart_policy: "unless-stopped"
|
||||||
|
env:
|
||||||
|
VINCE_DATA: /data
|
||||||
|
VINCE_LISTEN: "0.0.0.0:{{ vince_port }}"
|
||||||
|
# serve (re)creates the admin account from these on every boot —
|
||||||
|
# the env file is the source of truth, like the PocketBase superuser.
|
||||||
|
VINCE_ADMIN_NAME: "{{ vince_admin_name }}"
|
||||||
|
VINCE_ADMIN_PASSWORD: "{{ vince_admin_password }}"
|
||||||
|
# create the tracked site on startup (CSV list)
|
||||||
|
VINCE_DOMAINS: "{{ vince_site_domain }}"
|
||||||
|
VINCE_URL: "https://{{ stats_host }}"
|
||||||
volumes:
|
volumes:
|
||||||
- "{{ host_directory }}/vince_data:/data"
|
- "{{ host_directory }}/vince_data:/data"
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -20,9 +20,15 @@ docker_network: "{{ title }}_net"
|
|||||||
docker_image: "{{ registry }}/{{ title }}:{{ image_tag | default(tag) }}"
|
docker_image: "{{ registry }}/{{ title }}:{{ image_tag | default(tag) }}"
|
||||||
docker_container: "{{ title }}-staging"
|
docker_container: "{{ title }}-staging"
|
||||||
|
|
||||||
# self-hosted first-party analytics (Vince) — proxied at /stats/* on www host
|
# self-hosted first-party analytics (Vince) — script/events proxied at
|
||||||
|
# /stats/* on the www host, dashboard published on stats_host
|
||||||
vince_container: vince
|
vince_container: vince
|
||||||
vince_port: 8000
|
vince_port: 8000
|
||||||
|
vince_admin_name: admin
|
||||||
|
# change this before first deploy — it (re)sets the dashboard login
|
||||||
|
vince_admin_password: "ChangeMe-Vince-2025!"
|
||||||
|
vince_site_domain: mozimo.in
|
||||||
|
stats_host: stats.mozimo.in
|
||||||
|
|
||||||
# caddy publishes www (SSR + /api/* + /_/* -> pocketbase) and cms (admin)
|
# caddy publishes www (SSR + /api/* + /_/* -> pocketbase) and cms (admin)
|
||||||
|
|
||||||
|
|||||||
+11
-5
@@ -72,13 +72,19 @@ Shopify (shop.mozimo.in) ─ purchase/checkout ──► same GA4 property
|
|||||||
|
|
||||||
### 2.4 Vince (first-party layer)
|
### 2.4 Vince (first-party layer)
|
||||||
|
|
||||||
1. `./deploy.sh` once (the playbook creates the container + Caddy route).
|
1. `./deploy.sh` once — the playbook creates the container (`command: serve`)
|
||||||
2. Open `https://<www_host>/stats/` → register the admin account (first
|
with `VINCE_ADMIN_NAME` / `VINCE_ADMIN_PASSWORD` from
|
||||||
visit only). Then **Add a website** with domain `mozimo.in`.
|
`ansible/vars/default.yml` (change the password there before deploying)
|
||||||
|
and auto-creates the `mozimo.in` site via `VINCE_DOMAINS`.
|
||||||
|
2. Add a DNS record for `stats.mozimo.in` (same server IP) — Caddy publishes
|
||||||
|
the dashboard there; log in at `https://stats.mozimo.in/login` with the
|
||||||
|
admin name/password from the ansible vars.
|
||||||
3. Set `VITE_PLAUSIBLE_DOMAIN=mozimo.in` in your local `.env` and redeploy —
|
3. Set `VITE_PLAUSIBLE_DOMAIN=mozimo.in` in your local `.env` and redeploy —
|
||||||
the script tag is injected only when this is set.
|
the script tag (with `data-api="/stats/api/event"`) is injected only when
|
||||||
|
this is set.
|
||||||
4. Check `https://<www_host>/stats/js/script.js` returns the script (200)
|
4. Check `https://<www_host>/stats/js/script.js` returns the script (200)
|
||||||
and that browsing the site populates the dashboard within seconds.
|
and that browsing the site populates `stats.mozimo.in/<domain>` within
|
||||||
|
seconds.
|
||||||
5. With uBlock Origin enabled: visits still appear in Vince but not GA4 —
|
5. With uBlock Origin enabled: visits still appear in Vince but not GA4 —
|
||||||
expected and exactly why this layer exists.
|
expected and exactly why this layer exists.
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,9 @@ function analyticsHeadScripts() {
|
|||||||
src: "/stats/js/script.js",
|
src: "/stats/js/script.js",
|
||||||
defer: true,
|
defer: true,
|
||||||
"data-domain": PLAUSIBLE_DOMAIN,
|
"data-domain": PLAUSIBLE_DOMAIN,
|
||||||
|
// the tracker derives its event endpoint from the script origin
|
||||||
|
// by default; point it at the proxied path explicitly
|
||||||
|
"data-api": "/stats/api/event",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
|||||||
Reference in New Issue
Block a user