geometrikks-timescaledb
Docker app from GilbN's Repository
Overview
Readme
View on GitHubGeoMetrikks Unraid Templates
Unraid Community Apps templates for GeoMetrikks - a real-time geolocation analytics tool that tails your reverse proxy's access logs, does GeoIP lookups, and visualizes traffic on a live interactive map. It reads nginx, Traefik JSON and Caddy JSON logs, from a file or from Grafana Loki, and works out which is which per file.
This repository ships two Docker templates:
| Template | What it is |
|---|---|
geometrikks-timescaledb |
TimescaleDB + PostGIS database - install this first |
geometrikks |
The GeoMetrikks app and web UI |
Setup
1. Install the database
Add geometrikks-timescaledb from Community Apps. Set a POSTGRES_PASSWORD - you'll reuse this exact value in step 2. Leave POSTGRES_USER (geouser) and POSTGRES_DB (geometrikks) at their defaults unless you have a reason to change them.
The DB Port config (default 5432) is exposed to your LAN so the app container can reach it.
The template starts Postgres with timescaledb.max_background_workers=40 (and the matching max_parallel_workers / max_worker_processes). GeoMetrikks registers around 32 TimescaleDB jobs whose refresh policies all fire on the same tick, and the image's default of 16 workers can't cover that: the database log fills with failed to launch job ... out of background workers and continuous aggregates stop refreshing. If you installed this template before September 2026, remove and re-add the container to pick the setting up, or add the three -c flags yourself under Post Arguments.
2. Install the app
Add geometrikks from Community Apps and fill in:
- DB_HOST - your Unraid server's IP address (e.g.
192.168.1.50) - DB_PASSWORD - the same password you set for
geometrikks-timescaledbin step 1 - MAXMINDDB_USER_ID / MAXMINDDB_LICENSE_KEY - your free MaxMind GeoLite2 credentials (see step 3)
- MAP_CARTO_API_KEY - a free CARTO basemaps key from https://carto.com/basemaps/apikey. CARTO's terms require one per deployment, and keyless map tiles may stop working
- APP_ADMIN_USER / APP_ADMIN_PASSWORD - your web UI login, or APP_AUTH_DISABLED=true, or an identity provider (see below)
- Access Logs path - point this at wherever your reverse proxy writes its access logs (defaults to a SWAG-style path; change it for Nginx Proxy Manager, Traefik, Caddy, or whatever you actually run)
Leave DB_PORT/DB_USER/DB_DATABASE at their defaults unless you changed the matching values in step 1.
Signing in with an identity provider
GeoMetrikks 0.17.0 added OpenID Connect login, so the login page can hand you off to Authelia, Authentik, Keycloak, Pocket ID or Google. Four variables switch it on:
- OIDC_ISSUER - the provider's issuer URL, e.g.
https://auth.example.com - OIDC_CLIENT_ID / OIDC_CLIENT_SECRET - a confidential client you register for GeoMetrikks
- OIDC_REDIRECT_URI -
https://geo.example.com/api/v1/auth/oidc/callback, registered at the provider exactly as written
Then say who gets in, with OIDC_ALLOWED_USERS (verified email addresses or subject identifiers), OIDC_ALLOWED_GROUPS, or both. One of the two is mandatory and the container refuses to start without it, which beats discovering that every Google account on earth can read your traffic.
Two things to watch for on Unraid:
- The redirect URI is the public https address of the app, so this needs a TLS reverse proxy in front of the container, and APP_SESSION_SECURE=true with it.
http://<unraid-ip>:8000will not work as a redirect URI, and an https URI with a non-Secure cookie fails validation at startup. - Keep APP_ADMIN_PASSWORD set unless you want the provider to be the only way in. With both, the login page shows the provider button and the password form, which is what you want the day Authelia stops answering. Clear it and the password form disappears.
Per provider: Authelia works with the default OIDC_SCOPES (openid profile email groups) and serves groups from its userinfo endpoint, which GeoMetrikks reads. Authentik wants the issuer URL that ends in the application slug, and openid profile email unless you add a groups mapping. Google rejects the groups scope, so use openid profile email there and allow people by email. OIDC_LOGOUT_IDP only does something when the provider advertises an end_session_endpoint; Authelia 4.39 and Google do not, so leave it false for those. Settings > Status tells you whether the discovery document could be fetched.
The upstream README has the rest, including an Authelia client snippet to copy.
PUID / PGID and file ownership
The app container starts as root only long enough to remap its internal user to PUID:PGID, fix ownership of the GeoIP Data and App Logs folders, and then drop privileges - the app itself never runs as root. The template defaults to Unraid's usual 99:100 (nobody:users), which matches the rest of your appdata and the ownership SWAG/Nginx Proxy Manager give their log files, so no manual chown step is needed.
Your Access Logs mount is read-only and is not touched by that fix-up - those files just need to be readable by PUID:PGID on the host.
App logs
The App Logs path mount holds GeoMetrikks' own logs:
geometrikks.log- structured JSONL application loglogin.log- plain-text login/logout/failed-login events, in a format fail2ban and CrowdSec can parse
Both rotate by size and gzip their archives (LOG_MAIN_* / LOG_LOGIN_*). You can also browse and download them in the web UI under Settings -> Logs. Mounting the path is optional but recommended: without it the logs are lost whenever the container is recreated, and host-side tools can't read login.log.
Which log format?
The mount lands at /var/log/access inside the container whatever proxy you run, and LOGPARSER_LOG_PATHS names the file there. The format is detected per file, so Traefik and Caddy JSON logs need nothing beyond the path. Pin it with LOGPARSER_LOG_FORMATS (geometrikks-json, nginx, traefik-json, caddy-json) if detection gets it wrong.
Nginx is the one that needs work on your side: GeoMetrikks reads a keyed JSON log_format you have to add to your nginx.conf. The older positional format still parses, so an existing setup keeps working. Both are in the upstream README.
Tailing several files? LOGPARSER_LOG_PATHS takes a JSON list, and giving LOGPARSER_SERVER_NAME a list of the same length names each file separately, so the UI can filter them as separate servers.
Reading from Grafana Loki
If Alloy or Promtail already ships your proxy's access logs to Loki, GeoMetrikks can read them from there. The template doesn't list the Loki variables, because a blank LOKI_URL stops the app from starting. Add them with "Add another Path, Port, Variable":
- LOKI_URL - e.g.
http://192.168.1.50:3100. Use an address this container can reach, which on the default bridge network means your Unraid server's IP, notlocalhost. - LOKI_QUERIES - one LogQL stream selector, e.g. ``, or a JSON list of them, one source each.
- LOKI_SERVER_NAMES - optional, one name per selector. Without it every selector gets the first LOGPARSER_SERVER_NAME.
LOKI_USERNAME and LOKI_PASSWORD go together, for a Loki behind basic auth. The file in LOGPARSER_LOG_PATHS is still tailed next to Loki. Loki has to hold the raw access-log line, and Traefik's start-time timestamps need care. The upstream README covers both.
3. Get a free MaxMind GeoLite2 key
GeoMetrikks needs MaxMind's free GeoLite2 databases for GeoIP lookups:
- Sign up at https://www.maxmind.com/en/geolite2/signup
- Create a license key under your account
- Set MAXMINDDB_USER_ID and MAXMINDDB_LICENSE_KEY on the
geometrikkstemplate
The template requires both. Without them GeoMetrikks would run in degraded mode, with no GeoIP lookups.
Two databases are downloaded into the GeoIP Data mount: City, which drives the map and geo analytics, and ASN, which records the network behind each request and fills the Top ASNs view. Set GEOIP_ASN_ENABLED=false to skip the second one.
4. Open the web UI
http://<your-unraid-ip>:8000/ - log in with the admin credentials you set in step 2.
Notes
- Full environment variable reference: https://github.com/GilbN/geometrikks/blob/main/docs/configuration.md. Most of it is exposed as "advanced" settings on the
geometrikkstemplate - expand "Show more settings" when adding the container to see log parser tuning, log rotation, analytics retention, and map settings. Settings the template leaves out use the app's defaults, and you can add them with "Add another Path, Port, Variable". - LOGPARSER_IGNORE_IPS is worth setting: give it your own public IP (or any CIDR) to drop that traffic entirely - no geo event, access log or debug row. LAN traffic is never ingested in the first place, so this is for your own WAN-side hits.
- Reaching the UI through a TLS reverse proxy? Set APP_SESSION_SECURE=true, and put your proxy's IP/CIDR in APP_TRUSTED_PROXIES (e.g.
172.17.0.0/16) so client IPs are read fromX-Forwarded-For. LeaveAPP_SESSION_SECUREatfalseif you browse tohttp://<unraid-ip>:8000directly, or logins won't stick. - API_LOG_LEVEL is deprecated - use LOG_LEVEL. If an existing container still has it, delete the variable. Leaving it blank stops the app from starting.
- APP_PROXY_ADVISORY puts a warning on Settings > Status when the traffic in a tailed file comes from CDN or private addresses, which means your proxy is logging the hop in front of it instead of the visitor. Set it to
falseif that's deliberate (Tailscale-only access, a CDN you front on purpose). - APP_MODE is
fullhere and should stay that way.agentturns the container headless: no UI, no API, just tail, geolocate and write into a shared database. It's for a second GeoMetrikks next to another proxy, feeding this one. Give each agent its own APP_INSTANCE_NAME so it gets its own row on Settings > Agents. Two unnamed agents both go byagentand overwrite each other's status. - GeoMetrikks 0.21.0 renamed six variables. LOGPARSER_HOST_NAME is now LOGPARSER_SERVER_NAME, and the
MAP_HOME_*variables areMAP_SERVER_*: MAP_SERVER_LOCATIONS, MAP_SERVER_LATITUDE, MAP_SERVER_LONGITUDE, MAP_AUTO_DETECT_SERVER_LOCATION and MAP_SERVER_LOCATION_REFRESH_HOURS. The old names work until 1.0, and Settings > Status tells you which ones a container still reads. If a container has an old and a new name set to different values, the app refuses to start. Copy the value you set into the new variable, then delete the old one. - The template sets
--stop-timeout=20so the app can finish flushing its ingestion batch on shutdown. Unraid's default of 10 seconds kills it mid-write. - GeoMetrikks itself: https://github.com/GilbN/geometrikks
Requirements
Categories
Download Statistics
Total Downloads Over Time
Related apps
Explore more like this
Explore allDetails
timescale/timescaledb-ha:pg18Runtime arguments
- Network
bridge- Shell
sh- Privileged
- false
- Extra Params
--restart=unless-stopped --shm-size=512m --user 99:100
Template configuration
PostgreSQL port. Exposed to the host/LAN so the geometrikks app container can connect using the Unraid server's IP.
- Target
- 5432
- Default
- 5432
Database data directory. bPerformance tip:/b For best performance, use a path that bypasses the Unraid array (e.g. /mnt/cache/appdata or /mnt/appdata if configured). Paths under /mnt/user go through a FUSE layer that significantly slows database operations.
- Target
- /home/postgres/pgdata/data
Database password. Must match the DB_PASSWORD value you set in the geometrikks app template.
Database user. Must match DB_USER in the geometrikks app template - only change if you also change it there.
- Default
- geouser
Database name. Must match DB_DATABASE in the geometrikks app template - only change if you also change it there.
- Default
- geometrikks