Google quietly killed Timeline as a cloud feature in 2024 — your history now lives only on the device that recorded it, with no easy way to back it up, sync it, or analyze it across devices. If you ever pulled out Google Timeline to settle a “where were we in 2019?” debate, you’ve already noticed it’s not the same product. Dawarich brings that capability back, except you host it yourself, and Google never sees the data.
If you already self-host tools like Immich for photos, Home Assistant for device presence, or AdventureLog for trips, Dawarich is the missing timeline layer: it turns raw GPS pings into a searchable map history you control.
What is Dawarich?
Dawarich is a self-hostable web app that tracks, visualizes, and analyzes your location history. It’s positioned as a direct replacement for Google Timeline (formerly Google Location History) — same use cases, none of the data flowing to a third party.
“Dawarich is a self-hostable web app designed to replace Google Timeline. Track your location history, visualize your data on an interactive map, create trips, share your location with family members, and integrate with photo management apps.”
Dawarich on GitHub Dawarich Website Dawarich Documentation
What you can do with it
- 🗺️ Interactive maps — heatmap, point cloud, lines, fog of war (the “where have I been” overlay)
- 📅 Trips — name a date range and Dawarich computes the route, distance, and time spent
- 🏡 Areas and visits — draw a polygon around a location, get visit detection (beta)
- 👪 Family sharing — share your live location with family members who also use Dawarich
- 📊 Statistics and insights — countries visited, cities visited, total distance, days per country (handy for tax residency tracking)
- 🖼️ Photo integration — connect Immich or Photoprism and your geotagged photos appear on the map
- 📥 Import everywhere from — Google Takeout, OwnTracks, Strava, Immich, GPX, GeoJSON, photo EXIF
- 📤 Export anywhere to — GeoJSON, GPX
- 🌐 Public sharing — share a specific month’s stats with a UUID link that expires after a configurable window
- ⚖️ AGPL-3.0 — fully open source
How tracking works
Dawarich doesn’t include a built-in mobile tracker — instead it accepts pings from any OwnTracks-compatible app (or its own iOS/Android apps). You configure the tracker with your Dawarich URL + API key, and it POSTs location updates whenever your phone moves enough to be worth recording.
| App | Platform | Notes |
|---|---|---|
| Dawarich for iOS | iOS | Official app |
| Dawarich for Android | Android | Official app |
| OwnTracks | iOS / Android | The reference protocol; battle-tested |
| Overland | iOS | Battery-efficient background tracking |
| GPSLogger | Android | F-Droid available |
| Home Assistant | — | HA device_tracker entities can push to Dawarich |
Tech Stack in Brief
Backend: Ruby on Rails 8.0, PostgreSQL 17 + PostGIS 3.5, Sidekiq + Redis for background jobs, Devise for auth, Pundit for authorization. PostGIS is doing the heavy lifting — distance queries, point-in-polygon for visit detection, hexagon binning for the heatmap, all done as spatial SQL instead of Ruby loops.
Frontend: Hotwire (Turbo + Stimulus) + Tailwind CSS + DaisyUI. Direct JavaScript only for the map layer — Leaflet (v1 maps) and MapLibre GL JS (v2 maps). No React, no Vue, no SPA bundling.
Imports: Background-processed by Sidekiq. A 5-year Google Takeout archive can take hours to import — kick it off and walk away.
Self-Hosting Dawarich with Docker
Get Docker 🐋
Install Docker on your system before proceeding:
- Linux: Official Docker Engine install guide
- Windows / Mac: Docker Desktop
Verify installation: docker --version && docker compose version
Docker Compose
Four containers: app, sidekiq worker, Postgres-with-PostGIS, and Redis. The compose below is adapted from docker/docker-compose.yml in the repo:
networks:
dawarich:
services:
dawarich_redis:
image: redis:7.4-alpine
container_name: dawarich_redis
command: redis-server --save 900 1 --save 300 10 --appendonly no
networks: [dawarich]
volumes:
- dawarich_shared:/data
restart: always
dawarich_db:
image: postgis/postgis:17-3.5-alpine
# ARM hosts (Raspberry Pi, ARM VMs): use imresamu/postgis:17-3.5-alpine
shm_size: 1G
container_name: dawarich_db
volumes:
- dawarich_db_data:/var/lib/postgresql/data
networks: [dawarich]
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: changeme
POSTGRES_DB: dawarich_production
restart: always
dawarich_app:
image: freikin/dawarich:latest
container_name: dawarich_app
ports:
- "3000:3000"
volumes:
- dawarich_storage:/var/app/storage
- dawarich_public:/var/app/public
- dawarich_watched:/var/app/tmp/imports/watched
networks: [dawarich]
entrypoint: web-entrypoint.sh
command: ['bin/rails', 'server', '-p', '3000', '-b', '::']
environment:
RAILS_ENV: production
REDIS_URL: redis://dawarich_redis:6379
DATABASE_HOST: dawarich_db
DATABASE_USERNAME: postgres
DATABASE_PASSWORD: changeme
DATABASE_NAME: dawarich_production
APPLICATION_HOSTS: localhost,dawarich.example.com
APPLICATION_PROTOCOL: https
SECRET_KEY_BASE: REPLACE_WITH_64_HEX_BYTES # generate: openssl rand -hex 64
SELF_HOSTED: 'true'
STORE_GEODATA: 'true'
TIME_ZONE: Europe/London
restart: on-failure
dawarich_sidekiq:
image: freikin/dawarich:latest
container_name: dawarich_sidekiq
volumes:
- dawarich_storage:/var/app/storage
- dawarich_watched:/var/app/tmp/imports/watched
networks: [dawarich]
entrypoint: sidekiq-entrypoint.sh
command: ['sidekiq']
environment:
RAILS_ENV: production
REDIS_URL: redis://dawarich_redis:6379
DATABASE_HOST: dawarich_db
DATABASE_USERNAME: postgres
DATABASE_PASSWORD: changeme
DATABASE_NAME: dawarich_production
SECRET_KEY_BASE: REPLACE_WITH_64_HEX_BYTES
SELF_HOSTED: 'true'
BACKGROUND_PROCESSING_CONCURRENCY: 5
restart: on-failure
volumes:
dawarich_db_data:
dawarich_shared:
dawarich_public:
dawarich_watched:
dawarich_storage:
After docker compose up -d, open http://localhost:3000 and log in with the default credentials below. Change them immediately.
Default credentials: [email protected] / safepassword
ARM hosts (Raspberry Pi, ARM VMs)
The official postgis/postgis:17-3.5-alpine image is amd64-only. On ARM hosts, swap it for the community ARM-compatible image:
dawarich_db:
image: imresamu/postgis:17-3.5-alpine
Same Postgres + PostGIS versions, different builder. Everything else in the compose stays the same.
Why SELF_HOSTED=true is mandatory
Dawarich has a two-tier plan system (Lite / Pro) for the hosted Dawarich Cloud product. Lite caps data visibility at 12 months, disables several map layers (heatmap, fog of war), limits API rate, and blocks Immich/Photoprism integrations.
Setting SELF_HOSTED=true in the environment bypasses all of those restrictions — every user on your instance gets full Pro features unconditionally. If you forget to set it, your self-hosted instance will silently behave like the Cloud free tier.
The official docker-compose.yml ships with SELF_HOSTED: true as the default, but if you write your own compose from scratch, don’t omit it.
Enabling 2FA
TOTP 2FA is available but requires three encryption keys to be set:
environment:
OTP_ENCRYPTION_PRIMARY_KEY: <hex>
OTP_ENCRYPTION_DETERMINISTIC_KEY: <hex>
OTP_ENCRYPTION_KEY_DERIVATION_SALT: <hex>
Generate them with openssl rand -hex 32. Set the same three values on both the dawarich_app and dawarich_sidekiq containers.
Exposing Dawarich Safely
Dawarich contains sensitive location history, so do not expose it casually. For home labs, I would treat it like a private admin app:
- Keep it LAN-only if you only need access from home.
- Put it behind a VPN such as Tailscale or Headscale when you need mobile access.
- Use Cloudflare Tunnel or Pangolin only with authentication in front.
- Terminate HTTPS with Traefik, Caddy, or Nginx Proxy Manager if you expose it through a domain.
The data is more personal than a normal dashboard. Use 2FA, make backups, and avoid public registration.
Update Strategy (Important)
The project’s README ships an explicit warning: do not auto-update Dawarich. The codebase is under active development, releases include schema migrations, and a bad migration on top of unbacked-up data can lose history.
The recommended flow on every upgrade:
- Read the release notes for every version between yours and latest
- Back up the
dawarich_db_datavolume (Postgres dump or volume snapshot) - Pull the new image and
docker compose up -d - Watch logs until migrations finish before claiming success
Watchtower / auto-updaters are explicitly discouraged for this project.
Dawarich vs the Alternatives
| Dawarich | Google Timeline | OwnTracks | Home Assistant | |
|---|---|---|---|---|
| Self-hostable | Yes | No | Yes | Yes |
| Replaces Google Timeline | Yes | — | Partial | Partial |
| Polished map UI | Yes | Yes | Basic | Limited |
| Heatmap / fog of war | Yes | Yes | No | No |
| Trips with photo integration | Yes | Yes | No | No |
| Immich / Photoprism integration | Yes | No | No | No |
| Family sharing | Yes | Yes | Yes (broker-based) | Yes (HA-only) |
| Public sharing of a specific month | Yes (UUID link) | No | No | No |
| Receives data from OwnTracks/Overland/etc. | Yes | No | — | Yes |
The honest read: if you only need a backend to receive OwnTracks pings, OwnTracks Recorder is leaner. Home Assistant can do basic device_tracker history if you already run it. But for a Google Timeline-replacement experience — heatmap, fog of war, trips, statistics, photo integration — Dawarich is the only self-hosted option that comes close.
Conclusion
Dawarich fills a niche that became a hole when Google killed Timeline as a cloud product: a self-hosted location history app that actually looks and feels modern. The Rails 8 + PostGIS architecture is solid, the import pipeline accepts everything you’d reasonably have (including years of Google Takeout JSON), and the family sharing + Immich/Photoprism integrations push it past “just a tracker” into “actual replacement.”
It’s still actively developed and the maintainer warns clearly about breaking changes — treat it like the early-stage project it is, back up before every upgrade, and you’ll have a working Timeline replacement on your own hardware.
Related tools worth knowing:
- OwnTracks — the reference protocol for self-hosted location tracking; minimal backend, no fancy UI
- OwnTracks Recorder — lightweight OwnTracks backend in C; pairs with OwnTracks apps but no maps UI
- Traccar — fleet-oriented GPS server; more commercial-feeling but mature
- Immich — self-hosted photo library; pairs with Dawarich for geotagged photo visualization
Frequently Asked Questions
Is Dawarich really a Google Timeline replacement?
Functionally, yes. You get the same use cases: a heatmap of where you’ve been, statistics by country/city/year, a way to look back at “where was I on this date last year”. The biggest difference is that Dawarich is your own server — there’s no Google data harvesting, but also no automatic background tracking from your phone unless you install one of the supported tracker apps and grant it location permission.
How does it compare to OwnTracks alone?
OwnTracks is a tracker + a minimal recorder. It does one thing: log location pings. Dawarich is the front-end that turns those pings into trips, heatmaps, statistics, and family sharing. The natural pairing is OwnTracks (mobile) → Dawarich (server): use the OwnTracks mobile app for battery-efficient tracking, point it at your Dawarich instance for the polished UI.
Can I import my Google Takeout archive?
Yes — Google Maps Timeline is one of the supported import sources. Request a Takeout from Google with “Location History” selected, unzip the archive, and upload it through the Dawarich import UI. Large archives (5+ years) can take hours to process; Sidekiq runs the import in the background and shows progress.
What about battery drain?
Dawarich itself doesn’t drain your phone — the tracker app does. The OwnTracks app with “significant location change” mode is well-known for being battery-efficient (it uses the OS-provided coarse location instead of GPS-polling). Overland on iOS is similarly conservative. If you set a tracker to 1-second high-precision GPS, expect heavy battery use regardless of which backend receives the pings.
Do I need PostGIS specifically, or will plain Postgres work?
PostGIS is required. The points.lonlat column uses PostGIS geometry types, and the heatmap/visits queries use PostGIS spatial functions (ST_Within, ST_DWithin, hexagon binning). Plain Postgres won’t run the schema migrations.
Can I expose Dawarich through Cloudflare Tunnel?
Yes, but put authentication in front of it. A tunnel solves the networking problem, not the access-control problem. For a location-history app, use Cloudflare Access, Pangolin, Authelia, Tinyauth, or a VPN instead of publishing the raw Dawarich login page directly.
Can I run it on a Raspberry Pi?
Yes, but use the ARM-compatible PostGIS image (imresamu/postgis:17-3.5-alpine) — the official postgis/postgis image is amd64-only. Performance on a Pi 4 / 5 is fine for one user with a few years of history; large heatmap queries on millions of points will be slower than on x86.
How does family sharing work?
Each family member runs a Dawarich account on the same instance and opts in to sharing their location with specific other users. Sharing is consent-based and individually toggleable — a family member can revoke access at any time. You see each other’s locations on the same map view.
What’s the public sharing feature?
You can publish a single month’s statistics page with a UUID-based public URL. The link is unguessable (UUIDv4), expires after a configurable window (1 hour, 12 hours, 24 hours, or permanent), and exposes only that month’s aggregate data — never raw points and never other months. Useful for sharing a memorable travel month with friends without giving them access to your full history.
Comments