Home
Softono
n

noandrea

Professional software vendor delivering innovative solutions on the Softono platform. Specialized in both open-source and proprietary software development.

Total Products
1

Software by noandrea

Geo2tz
Open Source

Geo2tz

# Geo2Tz [![QA](https://github.com/noandrea/geo2tz/actions/workflows/quality.yml/badge.svg)](https://github.com/noandrea/geo2tz/actions/workflows/quality.yml) [![GoDoc](https://godoc.org/github.com/noandrea/geo2tz?status.svg)](https://godoc.org/github.com/noandrea/geo2tz) [![Go Report Card](https://goreportcard.com/badge/github.com/noandrea/geo2tz)](https://goreportcard.com/report/github.com/noandrea/geo2tz) A self-hostable service to get the timezone given geo-coordinates (lat/lng) Timezone data comes from [github.com/evansiroky/timezone-boundary-builder](https://github.com/evansiroky/timezone-boundary-builder). [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://stand-with-ukraine.pp.ua/) ## Maturity Level This project is considered mature and stable, having undergone extensive testing and refinement over time. It is now in a state where it can be reliably used in production environments. The badge below shows the number of Docker pulls for the project: <!-- ![Docker Pulls](https://img.shields.io/docker/pulls/noandrea/geo2tz?style=for-the-badge) --> ![GHCR Pulls](https://ghcr-badge.elias.eu.org/shield/noandrea/geo2tz/geo2tz) ### Contributing We value your feedback and contributions! If you encounter any bugs or have ideas for new features, please don't hesitate to [open an issue](https://github.com/noandrea/geo2tz/issues/new). Your input is crucial in helping us improve and evolve the project. ## Motivations Geo-coordinates can be sensitive information. This project provides a privacy-friendly, self-hosted solution that ensures coordinates are not leaked to third-party services. ## API The service exposes two endpoints: one to look up the timezone for a pair of coordinates, and one to report the version of the timezone database in use. ### Timezone lookup ```http GET /tz/${LATITUDE}/${LONGITUDE} ``` Returns a JSON reply (`http/200`), for example: ```console curl -s http://localhost:2004/tz/51.477811/0 | jq ``` ```json { "coords": { "lat": 51.47781, "lon": 0 }, "tz": "Europe/London" } ``` On invalid input it returns a `4xx` response, for example: ```console curl -v http://localhost:2004/tz/51.477811/1000 | jq * Trying 127.0.0.1:2004... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to localhost (127.0.0.1) port 2004 (#0) > GET /tz/51.477811/1000 HTTP/1.1 > Host: localhost:2004 > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 400 Bad Request < Content-Type: application/json; charset=UTF-8 < Vary: Origin < Date: Fri, 23 Jun 2023 19:09:29 GMT < Content-Length: 54 < { [54 bytes data] 100 54 100 54 0 0 89403 0 --:--:-- --:--:-- --:--:-- 54000 * Connection #0 to host localhost left intact ``` ```json { "message": "lon value 1000 out of range (-180/+180)" } ``` ### Database version The version of the database in use is exposed at `/tz/version`: ```console curl -s http://localhost:2004/tz/version | jq ``` ```json { "version": "2026b", "url": "https://github.com/evansiroky/timezone-boundary-builder/releases/tag/2026b", "geo_data_url": "https://github.com/evansiroky/timezone-boundary-builder/releases/download/2026b/timezones-with-oceans.geojson.zip" } ``` Coordinates are decimal degrees in the ranges `[-90, 90]` for latitude and `[-180, 180]` for longitude. ### Authorization Geo2Tz supports a basic token authorization mechanism, if the configuration value for `web.auth_token_value` is a non-empty string, geo2tz will check the query parameter value to authorize incoming requests. For example, running the service with: ```sh docker run --pull=always -p 2004:2004 -e GEO2TZ_WEB_AUTH_TOKEN_VALUE=secret ghcr.io/noandrea/geo2tz:latest ``` will enable authorization. With the authorization enabled, a query that does not specify the token will fail with an HTTP code 401: ```sh > curl -sv http://localhost:2004/tz/41.902782/12.496365 | jq ``` ``` * Trying 127.0.0.1:2004... * Connected to localhost (127.0.0.1) port 2004 (#0) > GET /tz/41.902782/12.496365 HTTP/1.1 > Host: localhost:2004 > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 401 Unauthorized < Content-Type: application/json; charset=UTF-8 < Vary: Origin < Date: Sun, 31 Jul 2022 20:06:56 GMT < Content-Length: 27 < { [27 bytes data] * Connection #0 to host localhost left intact { "message": "unauthorized" } ``` Passing the token in the query parameters will succeed instead: ```sh > curl -s http://localhost:2004/tz/41.902782/12.496365\?t\=secret | jq ``` ```json { "coords": { "lat": 41.902782, "lon": 12.496365 }, "tz": "Europe/Rome" } ``` ## Configuration Geo2Tz is configured via environment variables (prefixed with `GEO2TZ_`) or an optional config file. Defaults are listed below. | Environment variable | Default | Description | | --- | --- | --- | | `GEO2TZ_WEB_LISTEN_ADDRESS` | `:2004` | Address the HTTP server binds to. | | `GEO2TZ_WEB_AUTH_TOKEN_VALUE` | (empty) | When non-empty, enables token authorization. | | `GEO2TZ_WEB_AUTH_TOKEN_PARAM_NAME` | `t` | Query-parameter name carrying the auth token. | | `GEO2TZ_TZ_DATABASE_NAME` | bundled tz DB | Path to the timezone GeoJSON database. | | `GEO2TZ_TZ_VERSION_FILE` | bundled version file | Path to the version metadata file. | A config file is loaded automatically when present at `/etc/geo2tz/config.{yaml,toml,json}`. A custom path can be passed with `--config`. Keys mirror the env vars but are nested under `web.*` / `tz.*` (e.g. `web.auth_token_value`). ## Docker Docker image is available at [geo2tz](https://github.com/noandrea/geo2tz/pkgs/container/geo2tz) ```sh docker run --pull=always -p 2004:2004 ghcr.io/noandrea/geo2tz:latest ``` The image is built `FROM` [scratch](https://hub.docker.com/_/scratch), so it contains only the `geo2tz` binary and the bundled timezone database — no shell, package manager, or utilities. ## Docker Compose Docker Compose YAML example: ```yaml services: geo2tz: container_name: geo2tz image: ghcr.io/noandrea/geo2tz:latest # pin to a release tag for production deployments ports: - "2004:2004" restart: unless-stopped # uncomment to enable authorization via request token # environment: # GEO2TZ_WEB_AUTH_TOKEN_VALUE: ${GEO2TZ_TOKEN} # GEO2TZ_WEB_AUTH_TOKEN_PARAM_NAME: t # GEO2TZ_WEB_LISTEN_ADDRESS: ":2004" ``` The `version` top-level field has been removed from the Compose spec and is no longer needed. The image is built `FROM scratch`, so it has no shell or `wget`/`curl` — Compose healthchecks based on those will not work; use an external probe instead. ## K8s Kubernetes configuration example: ```yaml --- # Deployment apiVersion: apps/v1 kind: Deployment metadata: labels: app: geo2tz name: geo2tz spec: replicas: 1 revisionHistoryLimit: 3 selector: matchLabels: app: geo2tz template: metadata: labels: app: geo2tz spec: containers: - name: geo2tz image: ghcr.io/noandrea/geo2tz:latest # pin to a release tag for production deployments imagePullPolicy: Always ports: - name: http containerPort: 2004 # if GEO2TZ_WEB_AUTH_TOKEN_VALUE is non-empty, token authorization is enabled # env: # - name: GEO2TZ_WEB_AUTH_TOKEN_VALUE # value: "secretsmaybebetter" # default is empty # - name: GEO2TZ_WEB_AUTH_TOKEN_PARAM_NAME # value: "t" # default value # - name: GEO2TZ_WEB_LISTEN_ADDRESS # value: ":2004" # default value readinessProbe: httpGet: path: /tz/version port: http initialDelaySeconds: 2 periodSeconds: 10 livenessProbe: httpGet: path: /tz/version port: http initialDelaySeconds: 10 periodSeconds: 30 resources: requests: cpu: 50m memory: 128Mi limits: cpu: 500m memory: 512Mi --- # Service for the above deployment apiVersion: v1 kind: Service metadata: name: geo2tz-service spec: type: ClusterIP ports: - name: http port: 80 protocol: TCP targetPort: http selector: app: geo2tz ``` ## Development notes To update the timezone database you have a few options: 1. download the version specified in the `tzdata/version.json` file ```console geo2tz update current ``` 2. update to the latest version available ```console geo2tz update latest ``` 3. update to a specific version ```console geo2tz update 2023b ``` The `update` command downloads the timezone GeoJSON zip and writes a version file into the `tzdata` directory; the version file is used to track the current version of the database.

Route Planning
94 Github Stars