Try describing what you need:

SparkyFitness logo

SparkyFitness

★ 6.5k
proprietarySource-Available — Not OSS3 Containers — 3 containers — light hosting footprintCompose · BinaryNeeds Postgres1 documented maintainer

About

SparkyFitness is a self-hosted fitness and health tracking platform aimed at people who want to keep control of their data while logging a broad range of wellness information. It positions itself as...

Community Ratings

No ratings yet
image

Features

  • nutrition tracking
  • exercise tracking
  • hydration tracking
  • sleep tracking
  • fasting tracking
  • mood tracking
  • body measurement tracking
  • goal setting
  • daily check-ins
  • interactive charts and reports

Details

Last Updated
Oct 29, 2026
Created
Jun 21, 2025
Install Methods
docker-composebinary
Requirements
Docker Compose
Authentication
oidc-sso2falocal
API
REST
Backup & Export
api-exportcsv-export
Runtime / Stack
Docker
Privacy & Independence
Cloud: Optional
User Model
Multi-User
Deployment

Deployment: Docker Compose ✓3 Containers — light hosting footprintRuns as 3 containers

Run SparkyFitness

More ways to host

Is this your project? Sponsor a listing

Run SparkyFitness with Docker Compose

Compose file from the SparkyFitness project repository.

3 services · database: postgres · infra: postgres

no resource limits declared

needs persistent storage (3 volumes)

docker/docker-compose.prod.yml · @ 5364674 · scanned Oct 17, 2026

services:
  sparkyfitness-db:
    image: postgres:18.3-alpine
    container_name: sparkyfitness-db
    restart: always
    # Uncomment below to expose PostgreSQL to the host (e.g., for pgAdmin, DBeaver).
    # ports:
    #   - "${SPARKY_FITNESS_DB_PORT:-5432}:5432"
    environment:
      # These two are only read the first time the database initialises, so the
      # defaults below are what an install that never set them is already using.
      # Do not change them on an existing instance: PostgreSQL ignores the new
      # value and the server then authenticates with credentials that no longer
      # match. See docs/src/install/environment-variables.md.
      POSTGRES_DB: ${SPARKY_FITNESS_DB_NAME:-sparkyfitness_db}
      POSTGRES_USER: ${SPARKY_FITNESS_DB_USER:-sparky}
      POSTGRES_PASSWORD: ${SPARKY_FITNESS_DB_PASSWORD:-}
      # Uncomment the line below and comment the line above to use a file-based secret
      # POSTGRES_PASSWORD_FILE: /run/secrets/sparkyfitness_db_password
      PUID: 1000
      GUID: 1000
    volumes:
      - ${DB_PATH:-./postgresql}:/var/lib/postgresql
    # The server applies migrations at startup, so it must not race Postgres
    # while it is still initialising.
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    # Uncomment the below section to mount the file-based secrets
    #secrets:
    #  - sparkyfitness_db_password
    networks:
      - sparkyfitness-network # Use the new named network

  sparkyfitness-server:
    image: codewithcj/sparkyfitness_server:latest # Use pre-built image
    environment:
      # --- Database Connection ---
      SPARKY_FITNESS_DB_HOST: ${SPARKY_FITNESS_DB_HOST:-sparkyfitness-db} # Use the service name 'sparkyfitness-db' for inter-container communication
      SPARKY_FITNESS_DB_PORT: 5432 # Uses internal container port. Do NOT change this if SPARKY_FITNESS_DB_HOST is using container name.
      SPARKY_FITNESS_DB_NAME: ${SPARKY_FITNESS_DB_NAME:-sparkyfitness_db}
      SPARKY_FITNESS_DB_USER: ${SPARKY_FITNESS_DB_USER:-sparky}
      SPARKY_FITNESS_DB_PASSWORD: ${SPARKY_FITNESS_DB_PASSWORD:-}
      # Uncomment the line below and comment the line above to use a file-based secret
      # SPARKY_FITNESS_DB_PASSWORD_FILE: /run/secrets/sparkyfitness_db_password
      SPARKY_FITNESS_APP_DB_USER: ${SPARKY_FITNESS_APP_DB_USER:-sparky_app}
      SPARKY_FITNESS_APP_DB_PASSWORD: ${SPARKY_FITNESS_APP_DB_PASSWORD:-}
      # Uncomment the line below and comment the line above to use a file-based secret
      # SPARKY_FITNESS_APP_DB_PASSWORD_FILE: /run/secrets/sparkyfitness_app_db_password

      # --- Essential App Security ---
      SPARKY_FITNESS_FRONTEND_URL: ${SPARKY_FITNESS_FRONTEND_URL:-http://0.0.0.0:3004}
      SPARKY_FITNESS_API_ENCRYPTION_KEY: ${SPARKY_FITNESS_API_ENCRYPTION_KEY:-}
      # Uncomment the line below and comment the line above to use a file-based secret
      # SPARKY_FITNESS_API_ENCRYPTION_KEY_FILE: /run/secrets/sparkyfitness_api_key
      BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET:-}
      # Uncomment the line below and comment the line above to use a file-based secret
      # BETTER_AUTH_SECRET_FILE: /run/secrets/sparkyfitness_better_auth_secret

      # --- Server Runtime, Admin & Demo Mode ---
      NODE_ENV: ${NODE_ENV:-production}
      TZ: ${TZ:-Etc/UTC}
      SPARKY_FITNESS_LOG_LEVEL: ${SPARKY_FITNESS_LOG_LEVEL:-ERROR}
      SPARKY_FITNESS_SERVER_PORT: ${SPARKY_FITNESS_SERVER_PORT:-3010} # Port the backend listens on inside its container
      SPARKY_FITNESS_DISABLE_SIGNUP: ${SPARKY_FITNESS_DISABLE_SIGNUP:-false}
      SPARKY_FITNESS_ADMIN_EMAIL: ${SPARKY_FITNESS_ADMIN_EMAIL:-} # User with this email can access the admin panel
      SPARKY_FITNESS_DEMO_MODE: ${SPARKY_FITNESS_DEMO_MODE:-false}
      SPARKY_FITNESS_DEMO_EMAIL: ${SPARKY_FITNESS_DEMO_EMAIL:-}
      SPARKY_FITNESS_DEMO_PASSWORD: ${SPARKY_FITNESS_DEMO_PASSWORD:-}

      # --- Admin policy toggles (optional ENV override) ---
      # Also settable in the Admin UI, which stores them in global_settings.
      # Setting any of these to 'true' here forces it on regardless of the
      # stored value; leaving them empty defers to the Admin UI.
      SPARKY_FITNESS_PUBLIC_API_DOCS: ${SPARKY_FITNESS_PUBLIC_API_DOCS:-}
      DEV_TOOLS_ENABLED: ${DEV_TOOLS_ENABLED:-}
      ALLOW_PRIVATE_NETWORK_AI: ${ALLOW_PRIVATE_NETWORK_AI:-}
      ALLOW_PRIVATE_NETWORK_FOOD_PROVIDERS: ${ALLOW_PRIVATE_NETWORK_FOOD_PROVIDERS:-}

      # --- Network, Reverse Proxy & CORS ---
      ALLOW_PRIVATE_NETWORK_CORS: ${ALLOW_PRIVATE_NETWORK_CORS:-false}
      SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS: ${SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS:-}
      SPARKY_FITNESS_REAL_IP_HEADER: ${SPARKY_FITNESS_REAL_IP_HEADER:-}
      SPARKY_FITNESS_TRUSTED_PROXY_HOPS: ${SPARKY_FITNESS_TRUSTED_PROXY_HOPS:-}
      SPARKY_FITNESS_TRUSTED_PROXIES: ${SPARKY_FITNESS_TRUSTED_PROXIES:-}

      # --- Email Settings (optional) ---
      SPARKY_FITNESS_EMAIL_HOST: ${SPARKY_FITNESS_EMAIL_HOST:-}
      SPARKY_FITNESS_EMAIL_PORT: ${SPARKY_FITNESS_EMAIL_PORT:-}
      SPARKY_FITNESS_EMAIL_SECURE: ${SPARKY_FITNESS_EMAIL_SECURE:-}
      SPARKY_FITNESS_EMAIL_USER: ${SPARKY_FITNESS_EMAIL_USER:-}
      SPARKY_FITNESS_EMAIL_PASS: ${SPARKY_FITNESS_EMAIL_PASS:-}
      # Uncomment the line below and comment the line above to use a file-based secret
      # SPARKY_FITNESS_EMAIL_PASS_FILE: /run/secrets/sparkyfitness_email_pass
      SPARKY_FITNESS_EMAIL_FROM: ${SPARKY_FITNESS_EMAIL_FROM:-}

      # --- Login & OIDC Authentication (optional) ---
      SPARKY_FITNESS_FORCE_EMAIL_LOGIN: ${SPARKY_FITNESS_FORCE_EMAIL_LOGIN:-}
      SPARKY_FITNESS_DISABLE_EMAIL_LOGIN: ${SPARKY_FITNESS_DISABLE_EMAIL_LOGIN:-}
      SPARKY_FITNESS_DISABLE_PASSKEY_LOGIN: ${SPARKY_FITNESS_DISABLE_PASSKEY_LOGIN:-}
      SPARKY_FITNESS_FORCE_PASSKEY_LOGIN: ${SPARKY_FITNESS_FORCE_PASSKEY_LOGIN:-}
      SPARKY_FITNESS_OIDC_AUTH_ENABLED: ${SPARKY_FITNESS_OIDC_AUTH_ENABLED:-}
      SPARKY_FITNESS_OIDC_PROVIDER_SLUG: ${SPARKY_FITNESS_OIDC_PROVIDER_SLUG:-}
      SPARKY_FITNESS_OIDC_PROVIDER_NAME: ${SPARKY_FITNESS_OIDC_PROVIDER_NAME:-}
      SPARKY_FITNESS_OIDC_AUTO_REGISTER: ${SPARKY_FITNESS_OIDC_AUTO_REGISTER:-}
      SPARKY_FITNESS_OIDC_LOGO_URL: ${SPARKY_FITNESS_OIDC_LOGO_URL:-}
      SPARKY_FITNESS_OIDC_ISSUER_URL: ${SPARKY_FITNESS_OIDC_ISSUER_URL:-}
      SPARKY_FITNESS_OIDC_DOMAIN: ${SPARKY_FITNESS_OIDC_DOMAIN:-}
      SPARKY_FITNESS_OIDC_CLIENT_ID: ${SPARKY_FITNESS_OIDC_CLIENT_ID:-}
      # Uncomment the line below and comment the line above to use a file-based secret
      # SPARKY_FITNESS_OIDC_CLIENT_ID_FILE: /run/secrets/sparkyfitness_oidc_client_id
      SPARKY_FITNESS_OIDC_CLIENT_SECRET: ${SPARKY_FITNESS_OIDC_CLIENT_SECRET:-}
      # Uncomment the line below and comment the line above to use a file-based secret
      # SPARKY_FITNESS_OIDC_CLIENT_SECRET_FILE: /run/secrets/sparkyfitness_oidc_client_secret
      SPARKY_FITNESS_OIDC_SCOPE: ${SPARKY_FITNESS_OIDC_SCOPE:-}
      SPARKY_FITNESS_OIDC_AUTO_REDIRECT: ${SPARKY_FITNESS_OIDC_AUTO_REDIRECT:-}
      SPARKY_FITNESS_OIDC_ADMIN_GROUP: ${SPARKY_FITNESS_OIDC_ADMIN_GROUP:-}
      SPARKY_FITNESS_OIDC_TOKEN_AUTH_METHOD: ${SPARKY_FITNESS_OIDC_TOKEN_AUTH_METHOD:-}
      SPARKY_FITNESS_OIDC_ID_TOKEN_SIGNED_ALG: ${SPARKY_FITNESS_OIDC_ID_TOKEN_SIGNED_ALG:-}
      SPARKY_FITNESS_OIDC_USERINFO_SIGNED_ALG: ${SPARKY_FITNESS_OIDC_USERINFO_SIGNED_ALG:-}
      SPARKY_FITNESS_OIDC_TIMEOUT: ${SPARKY_FITNESS_OIDC_TIMEOUT:-}

      # --- Integrations ---
      GARMIN_MICROSERVICE_URL: ${GARMIN_MICROSERVICE_URL:-http://sparkyfitness-garmin:${GARMIN_SERVICE_PORT:-8000}} # Garmin microservice URL

      # --- Outbound Proxy Settings (optional) ---
      HTTP_PROXY: ${HTTP_PROXY:-} # Optional forward proxy for the server's outbound requests
      HTTPS_PROXY: ${HTTPS_PROXY:-}
      NO_PROXY: ${NO_PROXY:-}

      # --- Storage Paths (optional, standalone installs) ---
      SPARKY_FITNESS_CUSTOM_UPLOADS_DIRECTORY: ${SPARKY_FITNESS_CUSTOM_UPLOADS_DIRECTORY:-}
      SPARKY_FITNESS_CUSTOM_BACKUP_DIRECTORY: ${SPARKY_FITNESS_CUSTOM_BACKUP_DIRECTORY:-}

      # --- Rate Limiting (optional) ---
      SPARKY_FITNESS_SIGN_IN_RATELIMIT_MAX: ${SPARKY_FITNESS_SIGN_IN_RATELIMIT_MAX:-}
      SPARKY_FITNESS_SIGN_IN_RATELIMIT_WINDOW: ${SPARKY_FITNESS_SIGN_IN_RATELIMIT_WINDOW:-}
      SPARKY_FITNESS_API_KEY_RATELIMIT_WINDOW_MS: ${SPARKY_FITNESS_API_KEY_RATELIMIT_WINDOW_MS:-}
      SPARKY_FITNESS_API_KEY_RATELIMIT_MAX_REQUESTS: ${SPARKY_FITNESS_API_KEY_RATELIMIT_MAX_REQUESTS:-}

      PUID: 1000
      GUID: 1000
    networks:
      - sparkyfitness-network # Use the new named network
    restart: always
    depends_on:
      sparkyfitness-db:
        # Wait for Postgres to accept connections, not just for the container to
        # exist -- startup migrations run before the server listens.
        condition: service_healthy
    volumes:
      - ${SERVER_BACKUP_PATH:-./backup}:/app/SparkyFitnessServer/backup # Mount volume for backups
      - ${SERVER_UPLOADS_PATH:-./uploads}:/app/SparkyFitnessServer/uploads # Mount volume for Profile pictures and excercise images
    # Uncomment the below section to mount the file-based secrets
    #secrets:
    #  - sparkyfitness_db_password
    #  - sparkyfitness_app_db_password
    #  - sparkyfitness_api_key
    #  - sparkyfitness_better_auth_secret
    #  - sparkyfitness_email_pass
    #  - sparkyfitness_oidc_client_id
    #  - sparkyfitness_oidc_client_secret

  sparkyfitness-frontend:
    image: codewithcj/sparkyfitness:latest # Use pre-built image
    ports:
      # Container port must track NGINX_LISTEN_PORT, or nginx listens on an
      # unpublished port and the app becomes unreachable.
      - "${SPARKY_FITNESS_FRONTEND_PORT:-3004}:${NGINX_LISTEN_PORT:-80}"
    environment:
      SPARKY_FITNESS_FRONTEND_URL: ${SPARKY_FITNESS_FRONTEND_URL}
      # Where the frontend's nginx proxies /api, /health-data and /uploads.
      # This is resolved inside the frontend container, on the compose network,
      # so it must name the backend service — "localhost" here points at the
      # frontend itself and every API call returns 502. Only override it to
      # reach a backend outside this compose project. The port must match the
      # one passed to the server service above.
      SPARKY_FITNESS_SERVER_HOST: ${SPARKY_FITNESS_SERVER_HOST:-sparkyfitness-server}
      SPARKY_FITNESS_SERVER_PORT: ${SPARKY_FITNESS_SERVER_PORT:-3010}
      NGINX_RATE_LIMIT: ${NGINX_RATE_LIMIT:-5r/s}
      NGINX_RESOLVER: ${NGINX_RESOLVER:-}
      NGINX_LISTEN_PORT: ${NGINX_LISTEN_PORT:-}
      NGINX_ACCESS_LOG: ${NGINX_ACCESS_LOG:-}
      NGINX_ERROR_LOG: ${NGINX_ERROR_LOG:-}
      NGINX_DUMP_CONFIG: ${NGINX_DUMP_CONFIG:-false}
      PUID: 1000
      GUID: 1000
    networks:
      - sparkyfitness-network # Use the new named network
    restart: always
    depends_on:
      - sparkyfitness-server # Frontend depends on the server
      #- sparkyfitness-garmin # Frontend depends on Garmin microservice. Enable if you are using Garmin Connect features.

  # Garmin integration is still work in progress. Enable once table is ready.
  # sparkyfitness-garmin:
  #   image: codewithcj/sparkyfitness_garmin:latest
  #   container_name: sparkyfitness-garmin
  #   environment:
  #     GARMIN_MICROSERVICE_URL: http://sparkyfitness-garmin:${GARMIN_SERVICE_PORT}
  #     GARMIN_SERVICE_PORT: ${GARMIN_SERVICE_PORT}
  #     GARMIN_SERVICE_IS_CN: ${GARMIN_SERVICE_IS_CN}  # set to true for China region. Everything else should be false. Optional - defaults to false
  #     PUID: 1000
  #     GUID: 1000
  #   networks:
  #     - sparkyfitness-network
  #   restart: unless-stopped
  #   depends_on:
  #     - sparkyfitness-db
  #     - sparkyfitness-server

networks:
  sparkyfitness-network:
    driver: bridge

# Uncomment the below section to mount the file-based secrets
# These are the file paths on the host and should not be the same as the paths mentioned above which are in the containers themselves
#secrets:
#   sparkyfitness_db_password:
#     file: ${SPARKY_FITNESS_DB_PASSWORD_FILE:-./sparkyfitness_db_password.key}
#   sparkyfitness_app_db_password:
#     file: ${SPARKY_FITNESS_APP_DB_PASSWORD_FILE:-./sparkyfitness_app_db_password.key}
#   sparkyfitness_api_key:
#     file: ${SPARKY_FITNESS_API_ENCRYPTION_KEY_FILE:-./sparkyfitness_api_key.key}
#   sparkyfitness_better_auth_secret:
#     file: ${BETTER_AUTH_SECRET_FILE:-./sparkyfitness_better_auth_secret.key}
#   sparkyfitness_email_pass:
#     file: ${SPARKY_FITNESS_EMAIL_PASS_FILE:-./sparkyfitness_email_pass.key}
#   sparkyfitness_oidc_client_id:
#     file: ${SPARKY_FITNESS_OIDC_CLIENT_ID_FILE:-./sparkyfitness_oidc_client_id.key}
#   sparkyfitness_oidc_client_secret:
#     file: ${SPARKY_FITNESS_OIDC_CLIENT_SECRET_FILE:-./sparkyfitness_oidc_client_secret.key}

This file may be out of date. Check the SparkyFitness documentation for current setup steps.

Track your self-hosted stack

Bookmark software to try, rate tools you've used, and keep your collection in one place.

Metadata extracted from README on Oct 17, 2026

Related Software

MacroTrackr logo

MacroTrackr

16
A privacy-respecting macro tracker for logging meals, setting macro goals, tracking weight trends, and importing nutrition history.
Health & FitnessSelf Hosting SolutionsFully FOSS
2 ContainersFully FOSS
Details
NutriTrace logo

NutriTrace

356
NutriTrace is a self-hosted personal nutrition tracker for logging food, body stats, water, goals, and related health data with a browser PWA and Android app.
Health & FitnessRecipe ManagersSelf Hosting Solutions+2
Single Container
Details
openGym logo

openGym

17.1k
A self-hosted gym and body-weight tracker for planning workouts, logging sets and body weight, and syncing across devices with passkey login.
Health & FitnessSelf Hosting SolutionsAuthentication Services+1
3 Containers
Details
wger logo

wger

7.2k
wger is a free workout and fitness manager with routines, tracking, nutrition logging, and a built-in exercise wiki.
Health & FitnessWikisPhoto Galleries+3
Details
GymCoach logo

GymCoach

137
An open-source, self-hosted training tracker with an AI coach for logging workouts, tracking progress, and generating evidence-based debriefs and programs.
Health & FitnessSelf Hosting SolutionsArtificial Intelligence+2
3 ContainersFully FOSS
Details
ryot logo

ryot

3.6k
Ryot is a self-hosted platform for tracking media consumption and fitness activities in one place.
Personal DashboardsMedia ManagementHealth & Fitness+3
2 ContainersOpen CoreFully FOSS
Details
Schautrack logo

Schautrack

46
Schautrack is a self-hostable open-source nutrition tracker for logging calories, macros, weight, goals, and progress sharing.
Health & FitnessSelf Hosting SolutionsPersonal Dashboards+3
2 ContainersFully FOSS
Details
LiftTrace logo

LiftTrace

121
A self-hosted weightlifting tracker for logging workouts, programs, progress photos, stats, and AI-assisted coaching.
Health & FitnessSelf Hosting SolutionsAuthentication Services+1
Single Container
Details
Wingfit logo

Wingfit

538
Wingfit is a minimalist self-hosted fitness app for planning workouts, tracking personal records, and using smartwatch data.
Health & FitnessCopyleft LicenseSelf Hosting Solutions+2
Single Container
Details
openplate logo

openplate

69
openplate is an open-source, self-hosted food tracker with BYOK AI plate identification and encrypted device sync.
Health & FitnessSelf Hosting SolutionsArtificial Intelligence+1
Single ContainerFully FOSS
Details
Lyftr logo

Lyftr

362
Lyftr is a self-hosted, mobile-first workout and nutrition tracker that lets users log workouts, build programs, and track progress, weight, and calories.
Health & FitnessSelf Hosting SolutionsFully FOSS+1
2 ContainersFully FOSS
Details
SportTracker logo

SportTracker

20
SportTracker is a self-hosted server for recording and analyzing workout data, with support for multiple users, workout logs, goals, charts, maps, and planned tours.
Health & FitnessMaps and GPSAnalytics Tools+1
2 Containers
Details