SparkyFitness
★ 6.5kproprietarySource-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 yetNew this week
Read recap →Weekly Recap — Oct 16, 2026 – Oct 23, 2026Oct 23, 2026
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
- PikaPodsHosted for you, nothing to maintain(opens in a new tab)
- HetznerRun it on your own server. Plan for a small server.(opens in a new tab)
- DigitalOceanRun it on your own server. Plan for a small server.(opens in a new tab)
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.
Tags
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
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
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
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
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
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
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
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
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
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
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
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
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