This application automates the process of downloading GPX activity files from Garmin Connect and uploading them to a Dawarich instance.
Works with Dawarich 1.3.1
- Updates to the Dawarich app might break the upload (import) process.
- By default, the application will only work with tested versions of Dawarich. This can be changed in settings.
- Interactive Garmin Login (2FA/MFA supported): Log in to Garmin Connect directly from the Settings page in the web UI. Accounts with Two-Factor Authentication are fully supported -- enter your MFA code when prompted. No need to set Garmin credentials as environment variables.
- Automated Sync: Runs a scheduled job daily (at 3:00 AM) to download yesterday's activities from Garmin Connect and upload them to Dawarich.
- Manual Controls: Trigger downloads and uploads manually through the web interface.
- Historical Download: A "Custom Check" feature allows downloading historical data for a specified date range, with a configurable delay to avoid rate-limiting.
- Responsive Web UI: A clean web interface that works on both desktop and mobile devices for viewing records and managing the application.
- Intelligent Downloading: Skips activities that have already been downloaded or do not contain any GPS location data.
- Robust Uploading: Simulates browser behavior to robustly upload GPX files to Dawarich's direct upload endpoint.
- Connection & Version Checks: Performs pre-flight checks for Dawarich connection, credentials, and version compatibility to prevent errors.
- Persistent Database: Uses PostgreSQL or LiteFS (SQLite) to store a record of all downloaded files and their upload status.
- GeoPulse Integration: Optionally copies downloaded GPX files to a GeoPulse-compatible directory for additional location processing.
You can optionally enable GeoPulse support to automatically copy each downloaded GPX file to a GeoPulse-compatible path. When enabled, every GPX file saved from Garmin will also be copied to GEOPULSE_PATH/GEOPULSE_USER/filename.gpx.
To enable, set the following environment variables:
| Variable | Required | Description |
|---|---|---|
GEOPULSE_ENABLE |
No | Set to true to enable. Defaults to false. |
GEOPULSE_USER |
If enabled | The GeoPulse user EMAIL, used as a subdirectory. |
GEOPULSE_PATH |
If enabled | The base path where GeoPulse files are stored. |
All three must be set for the copy to take place. If the copy fails for any reason (permissions, disk space, etc.), the error is logged but does not interrupt the main download workflow.
Important: The GEOPULSE_PATH must be a shared volume mounted in both this container and the GeoPulse container. This allows GeoPulse to access the copied GPX files.
services:
garmin-to-dawarich-sync:
volumes:
- ./garmin-to-dawarich-sync:/garmin
- ./geopulse-data/import-drop:/geopulse # shared volume
environment:
GEOPULSE_PATH: "/geopulse"
geopulse:
volumes:
- ./geopulse-data:/geopulse # same shared volume- You can download historical location data from any period from Garmin.
- Set the start and end dates in the settings and run "Custom Check."
- The script will download one day at a time, proceeding to the next day after a delay.
- For significant time periods, consider setting a larger delay to avoid being flagged or banned by Garmin Connect.
- After GPX files are downloaded, you must trigger a manual upload to Dawarich.
- Docker
- A Garmin Connect account.
- A Dawarich instance.
Configuration is managed via environment variables. Below is an example snippet for a docker-compose.yml file.
environment:
# Flask settings
FLASK_SECRET_KEY: "your_very_secret_flask_key_here"
FLASK_ENV: "development"
# Garmin Connect Credentials (optional — you can log in via the Settings page instead)
# GARMIN_EMAIL: "your_garmin_email@example.com"
# GARMIN_PASSWORD: "your_garmin_password"
# Dawarich Instance Details
DAWARICH_EMAIL: "your_dawarich_email@example.com"
DAWARICH_PASSWORD: "your_dawarich_password"
DAWARICH_HOST: "https://dawarich.example.com"
# Garmin activity exclusion list (optional, Python list format)
# Example: EXCLUDE: "['Virtual Ride', 'Indoor Cycling']"
EXCLUDE: "[]"
# (Optional) GeoPulse Integration
GEOPULSE_ENABLE: "true"
GEOPULSE_USER: "your_geopulse_email"
GEOPULSE_PATH: "/path/to/geopulse"
# (Optional) PostgreSQL Database Details
POSTGRES_USER: "your_db_user"
POSTGRES_PASSWORD: "your_db_password"
POSTGRES_DB: "your_db_name"
POSTGRES_HOST: "db" # Often the service name in docker-compose- The application will automatically use a local LiteFS (SQLite) database located in the
/garminvolume if PostgreSQL environment variables are not fully provided. - To use PostgreSQL, you can use the same container as your Dawarich instance, but you must create a new, separate database for this application (e.g., using PGAdmin).
This project uses python-garminconnect to connect and interact with Garmin Connect services.
Please support Dawarich.
- The automated job runs at 3:00 AM every night according to the container's timezone.
- Navigate to
http://localhost:5000/(or your mapped port) to access the web interface.
- Allow customization of the scheduled job's time.
- Better styles for PC.
services:
garmin-to-dawarich-sync:
container_name: garmin-to-dawarich-sync
image: ghcr.io/pinionless/garmin-to-dawarich-sync:latest
volumes:
- ./garmin-to-dawarich-sync:/garmin
environment:
TZ: "America/Denver"
FLASK_SECRET_KEY: "fgxdrftg45eg5e4gerdg"
FLASK_ENV: "development"
# Garmin credentials are optional — log in via the web UI Settings page instead (supports 2FA)
# GARMIN_EMAIL: "email@example.com"
# GARMIN_PASSWORD: "your_garmin_password"
EXCLUDE: "['Indoor Rowing', 'Indoor Cycling']"
DAWARICH_EMAIL: "email@example.com"
DAWARICH_PASSWORD: "ABCDabcdd123"
DAWARICH_HOST: "https://dawarich.example.com"
# Optional GeoPulse Integration
# GEOPULSE_ENABLE: "true"
# GEOPULSE_USER: "your_geopulse_username"
# GEOPULSE_PATH: "/path/to/geopulse"
# Optional PostgreSQL connection
POSTGRES_USER: "myuser"
POSTGRES_PASSWORD: "mypassword"
POSTGRES_DB: "garmin-to-dawarich-sync"
POSTGRES_HOST: "postgres" # Assumes a service named 'postgres'