doable-server Quickstart
Three onboarding paths, five steps each. Pick the one that matches your situation; you can add the others later.
Screenshots: this guide intentionally stays text-only — the admin pages it references (
/admin/tracking,/admin/gsc,/admin/integrations, the route/project edit forms) render the real UI for your deployment, which is a more reliable walkthrough than stale PNGs. Every step below names the exact page you should be looking at.
Path 1 — Add analytics to an existing site
Use this when doable-server does not proxy your site, but you want its dashboard, consent banner, AI insights, and GSC view.
1. Create a tracking project
Admin panel → Tracking → New project. Name it (free text), add one or more domains the site is served from (one per line, no protocol).
Save. You get a dt_* tracking ID.
2. Copy the embed snippet
Tracking → your project → Embed. Two options:
- Script tag (simplest) — paste before
</body>. - Manual init — if you bundle JS yourself; same
dt_*ID.
For server-side tracking (Python/Flask/Django), see doable-tracker-python.
3. Enable cookie consent (optional, EU-facing sites)
In the tracking project edit form, toggle Require consent. Set a
Privacy URL (your privacy policy) and optionally custom banner text.
When set, the doable-tracker renders an Accept / Decline banner on first visit; declined visitors are not tracked.
4. Verify events are flowing
Visit your site once, wait ~30 seconds, then refresh the tracking project detail page. Events should start landing. The integration strip in the analytics view should show JS Tracker · Active.
5. (Optional) Connect GSC for this site
Jump to Path 3. The same service-account email applies to every integration on this server.
Path 2 — Host a site through doable-server
Use this when you want doable-server to serve the traffic as a reverse proxy, so you get server-side analytics without touching the site's HTML.
1. Create a route
Admin panel → Routes → New route. You need:
- A slug (used for
<slug>.doable.servicessubdomain and internal IDs). - A target — backend host and port (
192.168.x.x:8080). - Zero or more custom domains (one per line).
Save. The route is enabled by default.
2. Configure Apache
Copy one of the existing configs in /etc/apache2/sites-available/ as a
template (e.g. tajmad.se.conf). Edit the ServerName / ServerAlias
lines to match your domain, keep the ProxyPass line pointing at
http://127.0.0.1:5000/.
sudo a2ensite yourdomain.conf
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
sudo systemctl reload apache2
The doable-server Flask app (port 5000) routes by Host header.
3. Point DNS
Add an A record pointing your domain to the gateway's public IP
(155.4.75.114 in this deployment). Wait 1-5 minutes, verify with dig.
4. Enable privacy controls (recommended)
On the route edit form:
- Leave
PROXY_IP_TRUNCATEat its default (true) — proxy access logs store192.168.44.0/24instead of the full IP. - If you serve EU visitors and need full-IP only with consent, enable
Require proxy consent on the route. Visitors who decline (or send
DNT: 1) keep the minimized log row; explicit consent allows the full record.
5. Verify the route
Visit the domain. Admin Dashboard should show the route with 24-h traffic. The integration strip in the route's analytics view shows which capabilities are live.
Path 3 — Connect Google Search Console
Works on a route, a tracking project, or both. One email-paste per property. No OAuth.
1. Open the "Connect GSC" wizard
On the resource's edit form (route or tracking project), scroll to Google Search Console and click Connect. The 3-step wizard appears.
2. Grant the service account access
The wizard shows you an email address like
doable-gsc@your-project.iam.gserviceaccount.com. Copy it.
In Google Search Console → your property → Settings → Users and permissions → Add user. Paste the email, role Restricted. Save.
3. Verify
Back in the wizard, click Verify. doable-server calls the GSC API;
on success the property is saved as a GSCIntegration with status
verified.
If verification fails:
- Most common cause: property mismatch. Domain properties need
domaintype; URL-prefix properties need the fullhttps://...form. The wizard detects this and offers to switch. - Access error: re-check you added the exact email as a Restricted user, not an external email / manager role.
4. Wait for the first sync
The doable-gsc-sync PM2 process runs nightly at 04:00 and also
backfills the last GSC_INITIAL_BACKFILL_DAYS (default 480) days for a
fresh integration. You can trigger a manual sync from /admin/gsc →
Re-sync for any integration.
5. See search data in the dashboard
Open the route or project's analytics view. Once synced, the Search Console section (section #11 in the unified analytics layout) shows clicks, impressions, CTR, avg. position, top queries, top pages, device and country splits. The integration strip shows Search Console · 2h ago.
Common next steps
- Admin Integrations overview:
/admin/integrations— fleet-wide view of which resources have which capabilities, highlights anything needing attention. - Doable AI Insights: nothing to configure on a fresh install — it
runs nightly on every project that had activity in the last 7 days.
Per-user email alerts toggle at
/dashboard/settings. - Retention: defaults are sensible (90 d access logs, 2 y analytics, 7 y consent log). Override via env vars; see the GDPR compliance notes.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Tracker events never arrive | Consent banner shown and declined; or tracking ID mismatch | Check browser console for dt_consent=declined; verify dt_* ID |
| Integration strip shows Consent · Pending | TrackingProject.require_consent=true but no privacy_url set |
Set a privacy URL in project settings |
| GSC sync keeps failing | Service account removed from GSC property, or property revoked | Re-add the email; then /admin/gsc → Re-sync |
| AI Insights section never populates | No activity in last AI_INSIGHTS_ACTIVITY_DAYS (7 d) for the resource |
Wait for real traffic, or click Run now |
/admin/integrations shows Error badge |
3+ consecutive GSC sync failures | Check /admin/gsc last error, then re-verify or disconnect |