Self-Host FitTrackee: Free Fitness Tracking with Docker Compose

What Is FitTrackee?

FitTrackee is a self-hosted workout tracker that lets you log activities, upload GPX/FIT/TCX files, and visualize your routes on OpenStreetMap. It supports running, cycling, hiking, swimming, and custom sport types — with elevation profiles, pace charts, calorie tracking, and workout statistics. If you want Strava’s core tracking features without sending your workout data to a third party, FitTrackee delivers exactly that.

Official site: samr1.github.io/FitTrackee | GitHub

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 2 GB of free disk space
  • 1 GB of RAM (minimum)
  • A domain name (optional, for remote access)

Docker Compose Configuration

services:
  fittrackee:
    image: fittrackee/fittrackee:v1.1.2
    container_name: fittrackee
    restart: unless-stopped
    ports:
      - "5000:5000"
    environment:
      - HOST=0.0.0.0
      - PORT=5000
      - APP_SECRET_KEY=changeme_generate_a_random_secret_key
      - DATABASE_URL=postgresql://fittrackee:changeme_db@fittrackee-db:5432/fittrackee
      - REDIS_URL=redis://fittrackee-redis:6379
      - UI_URL=http://localhost:5000
      - EMAIL_URL=
      - [email protected]
      - WORKERS_PROCESSES=2
      - TILE_SERVER_URL=https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
      - STATICMAP_SUBDOMAINS=a,b,c
      - MAP_ATTRIBUTION=&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors
    depends_on:
      fittrackee-db:
        condition: service_healthy
      fittrackee-redis:
        condition: service_healthy
    volumes:
      - fittrackee-data:/usr/src/app/data
      - fittrackee-uploads:/usr/src/app/uploads
      - fittrackee-logs:/usr/src/app/logs
      - fittrackee-staticmap:/usr/src/app/.staticmap_cache
    networks:
      - fittrackee-net

  fittrackee-worker:
    image: fittrackee/fittrackee:v1.1.2
    container_name: fittrackee-worker
    restart: unless-stopped
    command: flask worker --processes 2
    environment:
      - APP_SECRET_KEY=changeme_generate_a_random_secret_key
      - DATABASE_URL=postgresql://fittrackee:changeme_db@fittrackee-db:5432/fittrackee
      - REDIS_URL=redis://fittrackee-redis:6379
      - UI_URL=http://localhost:5000
      - EMAIL_URL=
      - [email protected]
    depends_on:
      fittrackee-db:
        condition: service_healthy
      fittrackee-redis:
        condition: service_healthy
    volumes:
      - fittrackee-data:/usr/src/app/data
      - fittrackee-uploads:/usr/src/app/uploads
      - fittrackee-logs:/usr/src/app/logs
    networks:
      - fittrackee-net

  fittrackee-db:
    image: postgis/postgis:17-3.5-alpine
    container_name: fittrackee-db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=fittrackee
      - POSTGRES_PASSWORD=changeme_db
      - POSTGRES_DB=fittrackee
    volumes:
      - fittrackee-pgdata:/var/lib/postgresql/data
    networks:
      - fittrackee-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U fittrackee"]
      interval: 10s
      timeout: 5s
      retries: 5

  fittrackee-redis:
    image: redis:8.0-alpine
    container_name: fittrackee-redis
    restart: unless-stopped
    volumes:
      - fittrackee-redis:/data
    networks:
      - fittrackee-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  fittrackee-data:
  fittrackee-uploads:
  fittrackee-logs:
  fittrackee-staticmap:
  fittrackee-pgdata:
  fittrackee-redis:

networks:
  fittrackee-net:

Important: Replace changeme_generate_a_random_secret_key with a random string (use the same value in both services). Generate one with:

openssl rand -hex 32

Also change changeme_db to a strong database password.

Start the stack:

docker compose up -d

Initial Setup

  1. Open http://your-server-ip:5000 in your browser
  2. Click “Register” to create your admin account (the first registered user becomes admin)
  3. Go to Administration → Application to configure:
    • Maximum file size for GPX uploads (increase to 5-10 MB for long activities)
    • Maximum number of users (set to 1 for personal use)
    • Privacy policy URL (optional)

Key Features

FeatureDetails
Workout file importGPX, FIT, TCX, KML, and KMZ formats from any device or app
Route visualizationInteractive maps with OpenStreetMap tiles
Elevation profilesChart elevation gain/loss per workout, with optional elevation correction
Pace/speed chartsVisualize pace or speed segments across your route
Sport typesRunning, cycling, hiking, swimming, rowing, and fully custom types
StatisticsWeekly, monthly, yearly summaries with charts
Multi-userEach user has private workouts with separate stats
Equipment trackingAssociate gear (shoes, bikes) with workouts, track usage mileage
Calorie trackingExtracted from workout files or entered manually
Personal recordsPersonal bests tracked automatically across sport types
Dark modeBuilt-in dark theme
OAuth 2.0 APIFull REST API for integration with other tools and automation
PrivacyNo telemetry, no third-party data sharing
18+ languagesInternationalized UI with community translations

Configuration

Email Notifications

To enable password reset and email notifications, configure SMTP:

EMAIL_URL=smtp://user:[email protected]:587?tls=true
SENDER_EMAIL=[email protected]

Custom Map Tiles

The default uses OpenStreetMap tiles. For other tile providers, update TILE_SERVER_URL:

# Stamen Terrain (good for hiking)
TILE_SERVER_URL=https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}.png

# CartoDB Dark (for dark mode)
TILE_SERVER_URL=https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png

Elevation Correction

FitTrackee supports elevation correction using external APIs when GPS elevation data is inaccurate (common with phone GPS). Configure a Valhalla routing engine for accurate elevation:

VALHALLA_API_URL=http://your-valhalla-instance:8002

Alternatively, configure OpenElevation for simpler elevation correction without a full routing engine.

Limiting Registration

After creating your account, set the maximum users to prevent unwanted signups:

  1. Log in as admin
  2. Go to Administration → Application
  3. Set “Maximum number of active users” to 1 (or your desired limit)

Equipment Tracking

FitTrackee lets you track equipment (shoes, bikes, etc.) and associate them with workouts:

  1. Go to your profile → Equipment
  2. Add equipment with a name, type, and optional initial distance
  3. When logging or editing workouts, assign the equipment used
  4. FitTrackee tracks total distance on each piece of equipment — useful for knowing when to replace running shoes (typically every 500-800 km)

Connecting GPS Devices and Apps

FitTrackee doesn’t sync directly with Garmin, Wahoo, or Apple Watch — but there are solid workarounds for getting workout data in.

Android Companion Apps

These Android apps can record workouts and upload directly to your FitTrackee instance via its API:

AppFeaturesNotes
OpenTracksGPS recording, multi-sport, exports GPX/KMLOpen source, can be configured to share directly to FitTrackee
FitoTrackRunning/cycling focused, clean UIOpen source, GPX export
Runner UpDetailed running metrics, Bluetooth HR supportOpen source, exports GPX
GadgetbridgeSyncs with Mi Band, Amazfit, Garmin watchesOpen source, extracts workout data from smartwatches

Gadgetbridge is the key piece for smartwatch users — it connects to budget fitness watches (Amazfit, Mi Band, Pinetime) and can export workout GPX files that you upload to FitTrackee.

Garmin Workflow

No direct integration, but the workflow takes about 30 seconds:

  1. Record your workout on your Garmin device
  2. Sync to Garmin Connect (via phone or USB)
  3. In Garmin Connect, export the activity as GPX or FIT file
  4. Upload to FitTrackee through the web UI or API

For automation, use garmin-connect-export to batch-download GPX files, then upload them via FitTrackee’s API:

# Upload a GPX file via the API
curl -X POST "https://your-fittrackee.example.com/api/workouts" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "[email protected]" \
  -F "sport_id=1"

Bulk Import from Strava

Export your Strava data (Settings → My Account → Download or Delete Your Account → Request Your Archive). Strava sends a ZIP with all your GPX files. Upload them using a script:

#!/bin/bash
# Bulk upload GPX files to FitTrackee
API_URL="https://your-fittrackee.example.com/api/workouts"
TOKEN="your_oauth_token"

for gpx in export_*.gpx; do
  echo "Uploading $gpx..."
  curl -s -X POST "$API_URL" \
    -H "Authorization: Bearer $TOKEN" \
    -F "file=@$gpx" \
    -F "sport_id=1"
  sleep 1  # Rate limiting
done

Reverse Proxy

Update UI_URL to your public URL when using a reverse proxy:

UI_URL=https://fitness.example.com

For proxy configuration, see Reverse Proxy Setup.

Backup

Four volumes to back up:

  • fittrackee-pgdata — PostgreSQL database with all workout data and user accounts
  • fittrackee-uploads — uploaded GPX/FIT/TCX files (the originals)
  • fittrackee-data — application data
  • fittrackee-staticmap — cached map tile images (can be regenerated, optional)

Database dump:

docker compose exec fittrackee-db pg_dump -U fittrackee fittrackee > fittrackee-backup-$(date +%Y%m%d).sql

For a full backup strategy, see Backup Strategy.

Troubleshooting

GPX Upload Fails

Symptom: “Error during workout creation” when uploading a GPX file.

Fix: Check the file size limit in Administration → Application. The default is 1 MB. Increase it for longer activities. Also verify the GPX file is valid — FitTrackee requires proper <trk> elements with <trkpt> coordinates. FIT and TCX files are also supported as of v1.1.x.

Map Tiles Not Loading

Symptom: Workout map shows a gray background with no tiles.

Fix: Some tile providers rate-limit or require API keys. OpenStreetMap tiles work without authentication but have a usage policy. If you’re self-hosting for multiple users, consider running your own tile server or using a commercial provider.

PostGIS Extension Error

Symptom: Database migration fails with “extension postgis does not exist.”

Fix: Ensure you’re using the postgis/postgis image (not plain postgres). FitTrackee requires PostGIS for geographic queries. The postgis/postgis:17-3.5-alpine image includes the extension. Supported: PostgreSQL 14-18 with PostGIS 3.4-3.6.

Password Reset Not Working

Symptom: No email received after requesting password reset.

Fix: Configure EMAIL_URL with valid SMTP credentials. Check the application logs:

docker compose logs fittrackee | grep -i email

Worker Not Processing Uploads

Symptom: GPX uploads stay “pending” and never show workout data.

Fix: Ensure the fittrackee-worker container is running and Redis is healthy:

docker compose ps
docker compose logs fittrackee-worker

The worker handles background tasks like GPX processing, static map generation, and email sending. Without it, uploads queue up but never process.

FitTrackee vs Strava

The key question most people ask: can FitTrackee actually replace Strava?

FeatureFitTrackeeStrava FreeStrava Subscription ($11.99/mo)
Workout file importGPX, FIT, TCX, KML, KMZGPX, FIT, TCXGPX, FIT, TCX
Route mapsYes (OpenStreetMap)Yes (Mapbox)Yes (Mapbox)
Elevation profilesYes (+ elevation correction)YesYes
Pace/speed analysisYesBasicDetailed segments
Personal recordsYesYesYes
Equipment trackingYes (shoes, bikes, mileage)YesYes
Calorie trackingYes (from file + manual)YesYes
LeaderboardsNoYesYes
Segment matchingNoNoYes
Training plansNoNoYes
Live trackingNoNoYes
Direct device syncNo (GPX export needed)Yes (Garmin, Wahoo, Apple Watch)Yes
Social featuresNoYes (feed, kudos, comments)Yes
Route planningNoNoYes
HeatmapsNoNoYes
PrivacyFull (your server)Strava collects location dataStrava collects location data
Cost$0 (self-hosted)$0$143.88/year
Data ownershipFullStrava owns usage rightsStrava owns usage rights
Multi-userYes (per-instance)YesYes
APIFull REST + OAuth 2.0Limited (rate-limited)Limited (rate-limited)

The honest assessment: FitTrackee replaces Strava’s tracking and statistics features, plus adds equipment tracking and full data control. It does NOT replace the social layer (leaderboards, segments, kudos, activity feeds) or the device integration (direct Garmin/Wahoo/Apple Watch sync). If your workout routine is “record GPX → review stats,” FitTrackee handles that perfectly and saves you $144/year. If you chase segments, compete on leaderboards, or need live tracking, Strava is still ahead.

The workaround for device sync: Export GPX files from your Garmin/Wahoo device after each workout. Most devices let you do this via USB, Bluetooth, or the manufacturer’s app. It adds 30 seconds to your workflow but keeps your data private. See the Garmin workflow section above.

Resource Requirements

  • RAM: ~200 MB idle, ~500 MB during GPX processing (with worker and Redis)
  • CPU: Low — spikes briefly during GPX import, elevation correction, and static map generation
  • Disk: ~50 KB–5 MB per workout (GPX/FIT files are small). A daily runner generates ~10-15 MB/year. Static map cache grows with the number of unique routes.

Verdict

FitTrackee is the best self-hosted fitness tracker for people who primarily use GPS-based tracking (running, cycling, hiking). The v1.1.2 release adds FIT/TCX file support, equipment tracking, calorie tracking, and elevation correction — closing several gaps that earlier versions had versus Strava. The multi-format import (GPX, FIT, TCX, KML, KMZ) means you can bring workout data from virtually any GPS device or app.

Where it falls short compared to Strava is the social layer (no leaderboards, no segment matching) and device integration (no direct sync from Garmin/Wahoo). If you export workout files from your device and want to keep your data private, FitTrackee is the answer. If you need real-time device sync or social features, Strava is still hard to replace. Many users run both — FitTrackee as their private archive and Strava for the social experience.

FAQ

Can FitTrackee import from Strava?

Yes. Export your Strava data (Settings → My Account → Download or Delete Your Account → Request Your Archive). Strava sends a ZIP with all your GPX files. Upload them to FitTrackee one at a time through the web UI, or use the REST API for bulk import. See the bulk import script above. Note: Strava exports don’t include photos or social interactions.

Does FitTrackee sync with Garmin?

Not directly. FitTrackee has no Garmin Connect API integration. The workflow is: record on your Garmin → export GPX/FIT from Garmin Connect (or the device directly) → upload to FitTrackee. Tools like garmin-connect-export can automate the GPX download step. See the full Garmin workflow above.

What file formats does FitTrackee support?

FitTrackee v1.1.x supports GPX, FIT, TCX, KML, and KMZ files. GPX is the most universal format — virtually every GPS device and app can export it. FIT is Garmin’s native format and contains richer data (heart rate, cadence, power). TCX is another common format from older Garmin devices and some other manufacturers.

Can I track gym workouts in FitTrackee?

Partially. FitTrackee supports custom sport types, so you can log gym sessions with duration and calories. But it doesn’t track individual exercises, sets, reps, or weights — it’s designed for endurance/GPS sports. For strength training, look at wger instead. Many users run both: FitTrackee for outdoor activities, wger for the gym.

Is FitTrackee accurate enough for training?

For distance, pace, and elevation — yes, it’s as accurate as any tool that reads GPX data. The data comes from your GPS device, not FitTrackee. The elevation correction feature can improve accuracy when phone GPS gives bad altitude data. However, FitTrackee doesn’t calculate training load, VO2 max estimates, or recovery recommendations the way Garmin Connect or TrainingPeaks does. It’s a logging and visualization tool, not a training platform.

Can multiple family members use one FitTrackee instance?

Yes. FitTrackee supports multiple users with private workout data. Each user sees only their own workouts and statistics. The admin controls maximum user count and instance settings. Visibility settings let users optionally share specific workouts.

How do I export data from FitTrackee?

FitTrackee’s REST API lets you export all workout data programmatically. For individual workouts, download the original GPX/FIT file from the workout detail page. The API endpoints at /api/workouts return JSON with all metadata, and workout files are stored in the uploads volume — back up that directory and you have everything.

Does FitTrackee have a mobile app?

Not an official one. The web UI works well on mobile browsers. For recording workouts on your phone, use a companion app like OpenTracks, FitoTrack, or Runner Up (all open source Android apps) and export the GPX to FitTrackee. See the Android companion apps section for details.

Can I connect a smartwatch to FitTrackee?

Not directly. But Gadgetbridge (open source Android app) connects to many smartwatches (Amazfit, Mi Band, Pinetime, some Garmin models) and can export workout data as GPX files. Record on your watch → Gadgetbridge syncs to your phone → export GPX → upload to FitTrackee. It’s an extra step but keeps your watch data off cloud servers.

Does FitTrackee have an API?

Yes. FitTrackee has a full REST API with OAuth 2.0 authentication. You can create workouts, upload files (GPX/FIT/TCX), query statistics, manage equipment, and handle users programmatically. The API documentation is available at your-instance-url/api/docs once deployed. This makes it possible to build custom integrations — for example, a cron job that auto-imports GPX files from a sync folder.

How does FitTrackee compare to Garmin Connect?

FitTrackee handles workout logging, route maps, and statistics — the same core features Garmin Connect provides. What Garmin Connect has that FitTrackee doesn’t: direct device sync, Body Battery/sleep tracking, training readiness scores, and the Garmin ecosystem integration (IQ apps, Connect IQ). What FitTrackee has that Garmin doesn’t: full data ownership, no cloud dependency, multi-format import, and an open API. If you just want a workout archive you control, FitTrackee is the better choice. If you rely on Garmin’s training features, you’ll likely keep Garmin Connect alongside FitTrackee.

Comments