File: README.md
🌐 Language
[English](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=en)
[简体中文](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=zh-CN)
[繁體中文](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=zh-TW)
[日本語](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=ja)
[한국어](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=ko)
[हिन्दी](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=hi)
[ไทย](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=th)
[Français](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=fr)
[Deutsch](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=de)
[Español](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=es)
[Italiano](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=it)
[Русский](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=ru)
[Português](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=pt)
[Nederlands](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=nl)
[Polski](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=pl)
[العربية](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=ar)
[فارسی](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=fa)
[Türkçe](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=tr)
[Tiếng Việt](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=vi)
[Bahasa Indonesia](https://openaitx.github.io/view.html?user=CodeWithCJ&project=SparkyFitness&lang=id)SparkyFitness
A self-hosted, privacy-first alternative to MyFitnessPal. Track nutrition, exercise, body metrics, and health data while keeping full control of your data.
SparkyFitness is a self-hosted fitness tracking platform made up of:
- A backend server (API + data storage)
- A web-based frontend
- Native mobile apps for iOS and Android
It stores and manages health data on infrastructure you control, without relying on third party services.
Core Features
- Nutrition, exercise, hydration, sleep, fasting, mood and body measurement tracking
- Goal setting and daily check-ins
- Interactive charts and long-term reports
- Multiple user profiles and family access
- Light and dark themes
- OIDC, TOTP, Passkey, MFA etc.
How SparkyFitness Compares
SparkyFitness is source-available, not open source — the licence is non-commercial and requires permission for commercial use.
Most apps do one thing. One good nutrition app runs $40–$100 a year; covering everything SparkyFitness covers means three or four subscriptions, per person, and still no single report across them. SparkyFitness does it in one app, free, for the whole household.
US list prices, 14 Aug 2026. Full cost breakdown →
| SparkyFitness | wger | MyFitnessPal | Cronometer | Hevy | Zero | Flo | Garmin Connect | Google Health | |
|---|---|---|---|---|---|---|---|---|---|
| Self-hosted, your data stays yours | ⭐ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| No subscription, no ads | ✅ | ✅ | ❌ | 🟡 | 🟡 | ❌ | ❌ | ✅ | 🟡 |
| Nutrition, strength, sleep, fasting, cycle & meds in one place* | ⭐ | 🟡 | 🟡 | 🟡 | ❌ | ❌ | ❌ | 🟡 | 🟡 |
| Full history & custom date-range reports | ✅ free | 🟡 | 💰 | 💰 | 💰 | 💰 | 💰 | ✅ | 💰 |
| Wearable & health-platform sync | ✅ 8+ services | ❌ | ✅ | ⭐ | ✅ | 🟡 | 🟡 | 🟡 | ✅ |
| Family sharing with granular permissions | ⭐ 7 permissions | ❌ | ❌ | 🟡 | ❌ | ❌ | ❌ | 🟡 | 🟡 |
| CSV import & free data export | ✅ | 🟡 | 💰 | ✅ | ✅ | 🟡 | 🟡 | 🟡 | ❌ |
| MCP server + bring your own LLM | ⭐ | 🟡 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
⭐ standout • ✅ supported • 🟡 partial • 💰 paid tier only • ❌ not supported
* Sleep stages, HRV and blood glucose are imported from your watch, phone or meter. SparkyFitness stores, analyses and charts them rather than measuring them itself.
This table is written by the project being compared, so read it that way. Checked 14 Aug 2026 against official docs, repos and store listings; some of it is already out of date. If a cell is wrong or unfair to another project, open an issue — corrections that make SparkyFitness look worse are just as welcome.
See the full comparison → — 17 apps across self-hosted, nutrition, specialist and device-ecosystem categories, plus where each of them beats us.
Health & Device Integrations
SparkyFitness can sync data from multiple health and fitness platforms:
- Apple Health (iOS)
- Google Health Connect (Android)
- Google Health API
- Fitbit
- Garmin Connect
- Withings
- Polar Flow
- Oura
- Hevy
- OpenFoodFacts
- USDA
- Fatsecret
- Nutritionix
- Mealie
- Tandoor
- Strava (partially tested)
- Norish
- Yazio (uses unofficial API)
- Swiss Food Database
- Free Exercise DB (Github)
- Wger
Integrations automatically sync activity data such as steps, workouts, and sleep, along with health metrics like weight and body measurements, to your SparkyFitness server.
Optional AI Features (Beta)
SparkyAI provides a conversational interface for logging data and reviewing progress.
- Log food, exercise, body stats, and steps via chat
- Upload food images for automatic meal logging
- Retains conversation history for follow ups
Note: AI features are currently in beta.
Installation
Choose one of the two ways to run SparkyFitness:
1. Self-Hosted
Get a SparkyFitness server running in minutes using Docker Compose:
# 1. Create a new folder
mkdir sparkyfitness && cd sparkyfitness
# 2. Download Docker files only
curl -L -o docker-compose.yml https://github.com/CodeWithCJ/SparkyFitness/releases/latest/download/docker-compose.prod.yml
curl -L -o .env https://github.com/CodeWithCJ/SparkyFitness/releases/latest/download/default.env.example
# 3. (Optional) Edit .env to customize database credentials, ports, etc.
# 4. Start the app
docker compose pull && docker compose up -d
# Access application at http://localhost:8080Note: For other self-hosted installation methods, refer to the documentation at https://codewithcj.github.io/SparkyFitness/.
2. Cloud (for non-technical users)
If you are not a technical user and prefer not to run SparkyFitness on your own server, you can deploy a hosted instance in the cloud using one of the following providers.
Note: These are independent third-party services. We encourage you to explore features provided by each provider to determine the one that best fits your needs.
🎥 Video Tutorial
Quick 2-minute tutorial showing how to install SparkyFitness (self-hosted fitness tracker).
Documentation
For full installation guides, configuration options, and development docs, please visit our Documentation Site.
Quick Links
- Installation Guide - Deployment and configurations
- Features Overview - Complete feature documentation
- Development Workflow - Developer guide and contribution process
- iOS App Info and Android App Info
Need Help?
- Post in Github issues/discussion.
- For faster response and get help from other community memebers Join our Discord
Star History
Translations
Repository activity
Contributors
⚠️ Known Issues / Beta Features ⚠️
SparkyFitness is under active development.
Breaking changes may occur between releases.
- Auto-updating containers is not recommended
- Always review release notes before upgrading
The following features are currently in beta and may not have been thoroughly tested. Expect potential bugs or incomplete functionality:
- AI Chatbot
- Family & Friends access
- API documentation
File: docker/README.md
SparkyFitness Docker Configuration
This directory contains all Docker-related files for SparkyFitness deployment and development.
Refer to docs for more details
File: docs/content/1.install/1.docker-compose.md
Docker Compose [Recommended]
This page provides instructions for installing and running SparkyFitness using Docker Compose. This method is recommended for most users as it simplifies the setup process.
Prerequisites
Before you begin, ensure you have the following installed:
- Docker Desktop: Includes Docker Engine, Docker Compose, and Docker CLI.
Installation Steps
Create a new folder and download Docker files:
Create a new directory for SparkyFitness and navigate into it. Then, download the necessarydocker-compose.ymland.envfiles.bashmkdir sparkyfitness && cd sparkyfitness curl -L -o docker-compose.yml https://github.com/CodeWithCJ/SparkyFitness/releases/latest/download/docker-compose.prod.yml curl -L -o .env https://github.com/CodeWithCJ/SparkyFitness/releases/latest/download/default.env.exampleConfigure Environment Variables:
Thedocker-compose.ymlfile relies on environment variables defined in a.envfile.
Open the downloaded.envfile in a text editor and update the variables to customize your setup. It's crucial to configure these variables correctly for the application to function as expected.For a complete list of all available variables and their detailed descriptions, please refer to the example environment file:
.env.exampleon GitHubFor a comprehensive list of all available environment variables and their detailed descriptions, please refer to the Environment Variables documentation.
Start the Application:
From within thesparkyfitnessdirectory (wheredocker-compose.ymlis located), pull the latest images and start the application services:bashdocker compose pull && docker compose up -ddocker compose pull: Downloads the latest Docker images for the services.docker compose up -d: Starts the services defined in thedocker-compose.ymlfile in detached mode (in the background).
Services Overview
The docker-compose.prod.yml file defines three main services:
sparkyfitness-db:- Image:
postgres:15-alpine - Purpose: The PostgreSQL database server for storing application data.
- Data Persistence: Data is persisted in a Docker volume mapped to
../postgresqlon your host, ensuring your data is not lost if containers are removed.
- Image:
sparkyfitness-server:- Image:
codewithcj/sparkyfitness_server:latest - Purpose: The backend Node.js application server.
- Environment Variables: Configured with necessary database connection details, logging level, API encryption key, JWT secret, and frontend URL.
- Dependencies: Depends on
sparkyfitness-dbto ensure the database is running before the server starts.
- Image:
sparkyfitness-frontend:- Image:
codewithcj/sparkyfitness:latest - Purpose: The frontend React application served by Nginx.
- Ports: Maps host port
3004to container port80(Nginx), making the frontend accessible viahttp://localhost:3004(or your configured domain). - Dependencies: Depends on
sparkyfitness-serverto ensure the backend is running.
- Image:
Optional Services (Commented out by default)
To enable these services, open your docker-compose.yml file and uncomment the relevant blocks.
sparkyfitness-garmin:- Image:
codewithcj/sparkyfitness_garmin:latest - Purpose: A dedicated microservice for syncing data directly from Garmin Connect.
- Image:
Accessing the Application
Once all services are up and running, you can access the SparkyFitness frontend in your web browser at the URL you configured for SPARKY_FITNESS_FRONTEND_URL (e.g., http://localhost:3004).
Stopping and Removing Services
To stop the running services without removing their data volumes:
docker compose stopTo stop and remove all services, networks, and volumes (this will delete your database data!):
docker compose down -v
---
## File: docs/content/1.install/2.portainer.md
# Portainer Installation Guide
This guide provides step-by-step instructions on how to install and deploy SparkyFitness using Portainer. Portainer simplifies Docker management through a user-friendly web interface.
## Prerequisites
Before you begin, ensure you have:
1. **A running Docker environment**: Portainer requires Docker to be installed on your server.
2. **Portainer installed and configured**: Access to your Portainer instance. If you haven't installed Portainer yet, follow the official Portainer documentation.
## Step 1: Create a New Stack in Portainer
1. **Log in to Portainer**.
2. Navigate to **Stacks** in the left sidebar.
3. Click **Add stack**.
4. **Name your stack** (e.g., `sparkyfitness`).
5. Select **Upload** for the build method.
6. **Upload File**: Download the [docker-compose.prod.yml](https://github.com/CodeWithCJ/SparkyFitness/releases/latest/download/docker-compose.prod.yml) from the latest release and upload it here.
7. (Optional) You can also use the **Web editor** method and copy-paste the content if you prefer.
8. **Environment variables**: For a comprehensive list of all available environment variables and their detailed descriptions, please refer to the [Environment Variables documentation](/install/environment-variables). You will need to add these environment variables directly in Portainer.
## Step 2: Deploy the Stack
1. After configuring the stack, click the **Deploy the stack** button.
2. Portainer will now pull the necessary Docker images and create the containers for SparkyFitness. This process may take a few minutes depending on your internet connection.
## Step 3: Access SparkyFitness
Once the stack is successfully deployed and all containers are running, you can access the SparkyFitness frontend in your web browser.
* Open your web browser and navigate to the URL you configured for `SPARKY_FITNESS_FRONTEND_URL` in your environment variables (e.g., `http://your-server-ip:3004`).
You should now see the SparkyFitness login/signup page.
---
## File: docs/content/1.install/3.synology.md
# Synology Community Guide
This guide provides instructions for installing SparkyFitness on your Synology NAS, provided by the community.
For detailed instructions, please refer to the external guide:
[How to Install SparkyFitness on your Synology NAS by MariusHosting](https://mariushosting.com/how-to-install-sparkyfitness-on-your-synology-nas/)
---
## File: docs/content/1.install/4.proxmox.md
# Proxmox Installation Guide
This guide provides instructions for installing SparkyFitness on Proxmox VE using a script provided by the community.
**Note: This script is provided via community contribution and is not maintained directly by the SparkyFitness.**
For installation instructions and to use the script, please refer to the Proxmox VE Helper-Scripts website:
[SparkyFitness Proxmox VE Helper-Script](https://community-scripts.org/scripts/sparkyfitness?from=scripts&fromQ=sparkyfitness)
If you encounter issues related to the Proxmox installation, please report them using the "Report Issue" option on the page above.
Since I do not personally use Proxmox, I may not be able to provide much help with this installation method, but the script maintainers and community there should be able to assist.
---
## File: docs/content/1.install/5.kubernetes.md
::alert{type="warning"}
**Community Contribution:** The Kubernetes and Helm chart support are community-provided. The SparkyFitness maintainers do not currently use Kubernetes and cannot provide full review or official support for this installation method.
::
## Quick Start (Kubernetes)
Deploy SparkyFitness on Kubernetes using the Helm chart directly from the repository.
```bash
# 1. Install with default settings (bundled PostgreSQL, no ingress)
helm install sparkyfitness oci://ghcr.io/codewithcj/charts/sparkyfitness
# -- OR install directly from source --
git clone https://github.com/CodeWithCJ/SparkyFitness.git
helm install sparkyfitness ./SparkyFitness/helm/chart
# 2. (Optional) Customize values
helm install sparkyfitness ./SparkyFitness/helm/chart -f my-values.yaml
# 3. Access the application in browser via Ingress or HTTPRoute you've specified in valuesFor all configuration options (external database, ingress, OIDC, email, etc.) see the Helm chart README.
File: docs/content/1.install/6.build-from-source.md
Build from Source
Run SparkyFitness directly on your machine without Docker. You will need Node.js, pnpm, and a running PostgreSQL instance.
Prerequisites
- Node.js 24 or later
- pnpm — install with
npm install pnpm - PostgreSQL 17 or later
1. Clone the repository
git clone https://github.com/CodeWithCJ/SparkyFitness.git
cd SparkyFitness2. Install dependencies
pnpm install3. Configure environment variables
Copy the example env file to the repo root and fill in your values:
Linux / macOS
cp docker/.env.example .envWindows (PowerShell)
Copy-Item docker\.env.example .envRequired values to set in .env:
| Variable | Description |
|---|---|
SPARKY_FITNESS_DB_HOST |
PostgreSQL host — use localhost for local installs |
SPARKY_FITNESS_DB_NAME |
Database name (e.g. sparkyfitness_db) |
SPARKY_FITNESS_DB_USER |
Superuser used for migrations (e.g. sparky) |
SPARKY_FITNESS_DB_PASSWORD |
Superuser password |
SPARKY_FITNESS_APP_DB_USER |
App user with limited privileges (e.g. sparky_app) |
SPARKY_FITNESS_APP_DB_PASSWORD |
App user password |
SPARKY_FITNESS_FRONTEND_URL |
Set to http://localhost:8080 for local builds |
SPARKY_FITNESS_API_ENCRYPTION_KEY |
64-character hex string — generate with openssl rand -hex 32 or node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" |
BETTER_AUTH_SECRET |
Strongly recommended — auto-generated if absent but sessions will not survive server restarts. Signs sessions and encrypts 2FA/TOTP data. Never change after users have enabled 2FA or they will be locked out. |
Note: The default
SPARKY_FITNESS_DB_HOSTin the example file is set to a Docker service name. Change it tolocalhostfor a local install.
4. Set up PostgreSQL
Create the superuser and database that match your .env values.
Linux
sudo -u postgres createuser --pwprompt sparky
sudo -u postgres createdb sparkyfitness_db --owner sparkymacOS (Homebrew) — drop the sudo -u postgres prefix if your current user already has PostgreSQL superuser rights:
createuser --pwprompt sparky
createdb sparkyfitness_db --owner sparkyWindows — open a terminal and use psql as the postgres user (adjust the path to match your PostgreSQL install):
psql -U postgres -c "CREATE ROLE sparky WITH LOGIN PASSWORD 'yourpassword';"
psql -U postgres -c "CREATE DATABASE sparkyfitness_db OWNER sparky;"The sparky_app application user is created automatically by the server on first startup — you do not need to create it manually. Database migrations also run automatically on server start.
5. Start the backend server
cd SparkyFitnessServer
pnpm startThe API server starts on port 3010 by default. On first run it applies all migrations and creates the app database user. API docs are available at http://localhost:3010/api/api-docs/swagger.
6. Start the frontend
Open a second terminal from the repo root:
cd SparkyFitnessFrontend
pnpm devThe web app starts on port 8080 by default. Open http://localhost:8080 in your browser.
Port summary
| Service | Default URL |
|---|---|
| Backend API | http://localhost:3010 |
| Frontend | http://localhost:8080 |
| API Docs | http://localhost:3010/api/api-docs/swagger |
File: docs/content/1.install/7.environment-variables.md
Environment Variables
This document provides a comprehensive list and detailed descriptions of all environment variables used by SparkyFitness. Proper configuration of these variables is crucial for the application to function as expected.
For a complete list of all available variables and their detailed descriptions, please refer to the example environment file:.env.example on GitHub
::alert{type="warning"}
Important Note for Docker Compose Users:
For an environment variable defined in your .env file to be recognized by the application running inside a Docker container, it must be explicitly passed to that service in your docker-compose.yml file. If you add a new variable to your .env file that is not already present in the environment: section of the sparkyfitness-server (or sparkyfitness-garmin) service, the application will not see it.
::
Essential Configuration
The following environment variables are mandatory and must be supplied for the application to start correctly. Failure to provide these will result in the server failing to launch.
SPARKY_FITNESS_DB_NAME: Your desired PostgreSQL database name (e.g.,sparkyfitness_db).SPARKY_FITNESS_DB_USER: Your desired PostgreSQL database user (e.g.,sparky). This user is used for DB initialization and migrations.SPARKY_FITNESS_DB_PASSWORD: A strong password for your PostgreSQL database. This shouldn't be changed after initial setup. If you need to change it, you will need to update the password in the database and update this env variable.SPARKY_FITNESS_APP_DB_USER: Application database user with limited privileges. It can be changed any time after initialization.SPARKY_FITNESS_APP_DB_PASSWORD: Password for the application database user.SPARKY_FITNESS_FRONTEND_URL: The public URL of your frontend (e.g.,http://localhost:8080for local testing, or your domain likehttps://fitness.example.comfor production). This is crucial for CORS security.SPARKY_FITNESS_API_ENCRYPTION_KEY: A 64-character hex string for data encryption. You can generate one using:openssl rand -hex 32node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"SPARKY_FITNESS_API_ENCRYPTION_KEY_FILE: (Optional) Path to a file containing the encryption key. Useful for Docker Swarm/Kubernetes secrets. When this variable is set, the application will read the encryption key from the specified file path, allowing for more secure secret management in containerized environments.
BETTER_AUTH_SECRET: A secret key used by Better Auth to sign sessions and tokens. Make this a long, random, and secure string. You can generate one using:openssl rand -hex 32node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"[!CAUTION]
CRITICAL for 2FA/TOTP: This secret is used to encrypt Two-Factor Authentication (2FA) data in the database. If you change this variable after users have enabled 2FA, the server will lose access to their codes, and all 2FA users will be locked out of their accounts. This variable must be set to a persistent value during initial setup and should never be changed. If you must change it, you must ensure that ALL users have disabled Two-Factor Authentication (TOTP) first.
Mandatory Volume Paths
These paths define where Docker volumes will store persistent data on your host. These are mandatory to prevent data loss if containers are removed. You can either define them in the .env file or directly in the docker-compose.yml.
DB_PATH: Path for PostgreSQL database data (e.g.,../postgresql).SERVER_BACKUP_PATH: Path for server backups (e.g.,./backup).SERVER_UPLOADS_PATH: Path for profile pictures and exercise images (e.g.,./uploads).
Optional Configuration
The following variables are optional and can be used to customize your SparkyFitness installation.
Front End Variables
These variables control frontend behavior and should be passed to the sparkyfitness-frontend service
in your docker-compose.yml.
SPARKY_FITNESS_SERVER_HOST: Hostname of the backend server.SPARKY_FITNESS_SERVER_PORT: Port on which the backend serer is running.SPARKY_FITNESS_FRONTEND_URL: The frontend URL on which the server will be accessible, useful for reverse proxies.NGINX_LISTEN_PORT: The port on which nginx should listen. Defaults to80when running as root and8080when running as non-root.NGINX_ACCESS_LOG: The access log path for nginx. Defaults to/var/log/nginx/access.logwhen running as root and/dev/stdoutwhen running as non-root.NGINX_ERROR_LOG: The error log path for nginx. Defaults to/var/log/nginx/error.logwhen running as root and/dev/stderrwhen running as non-root.NGINX_DUMP_CONFIG: Always dump the complete nginx configuration on startup. The configuration should
always be dumped if it's invalid. Defaults to "false".
Server Side Variables
These variables control backend behavior and should be passed to the sparkyfitness-server service in your docker-compose.yml.
SPARKY_FITNESS_DISABLE_EMAIL_LOGIN: Set totrueto disable email/password login on the login page (overridden bySPARKY_FITNESS_FORCE_EMAIL_LOGIN).SPARKY_FITNESS_LOG_LEVEL: Logging level for the server (e.g.,INFO,DEBUG,WARN,ERROR).NODE_ENV: Node.js environment mode (e.g.,development,production,test). Set toproductionfor deployment to ensure optimal performance and security.TZ: Server timezone. Use a TZ database name (e.g.,America/New_York,Etc/UTC).SPARKY_FITNESS_DISABLE_SIGNUP: Set totrueto disable new user registrations.SPARKY_FITNESS_ADMIN_EMAIL: Set the email of a user to automatically grant admin privileges on server startup. If not set, no admin user will be created automatically.SPARKY_FITNESS_FORCE_EMAIL_LOGIN: Set totrueto force email/password login to be enabled, overriding any in-app settings. This is a fail-safe to prevent being locked out if OIDC is misconfigured.ALLOW_PRIVATE_NETWORK_CORS: Set totrueto allow Cross-Origin Resource Sharing (CORS) from private network addresses (e.g.,192.168.x.x,10.x.x.x,127.0.0.1,localhost). Use with caution.ALLOW_PRIVATE_NETWORK_AI: Set totrueto let non-admin users point custom AI service URLs (custom,ollama,openai_compatible) at private network addresses (e.g.,192.168.x.x,127.0.0.1,localhost). Admins and global AI settings can always use private URLs, so most self-hosted setups don't need this. Warning: enabling it lets any registered user make the server send requests to your internal network (SSRF) — only enable on a trusted single-tenant deployment. Defaults tofalse.SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS: A comma-separated list of additional URLs that Better Auth should trust (e.g.,http://192.168.1.175:8080). Use this if you are accessing the app from specific local IPs andALLOW_PRIVATE_NETWORK_CORSis enabled.SPARKY_FITNESS_DB_HOST: The hostname of the PostgreSQL database. For Docker Compose, this defaults tosparkyfitness-db(the service name). Only change this if you are using an external database server.SPARKY_FITNESS_DB_PORT: Controls the host port exposed for external database access (e.g., pgAdmin). Important: Inside Docker, containers always communicate on port5432. Changing this value in.envwill not affect container-to-container communication unless you are using an external database server.
To use this, you must also uncomment theportssection under thesparkyfitness-dbservice in yourdocker-compose.ymlfile.SPARKY_FITNESS_SERVER_HOST: The hostname or IP of the backend server. Primarily used by the internal Nginx proxy (not to be confused with your proxy manager) in the frontend container to route API requests. For Docker Compose, this defaults tosparkyfitness-server.SPARKY_FITNESS_SERVER_PORT: The server port (e.g.,3010). Defaults to3010. This is also used by the internal Nginx proxy (not to be confused with your proxy manager) in the frontend container.SPARKY_FITNESS_PUBLIC_API_DOCS: Set totrueto make the Swagger API documentation (/api/api-docs) publicly accessible without logging in. Defaults tofalse.
Email Settings (Server Side)
Configure these variables to enable email notifications (e.g., for password resets). If not configured, email functionality will be disabled.
SPARKY_FITNESS_EMAIL_HOST: SMTP host (e.g.,smtp.example.com).SPARKY_FITNESS_EMAIL_PORT: SMTP port (e.g.,587).SPARKY_FITNESS_EMAIL_SECURE: Usetruefor TLS/SSL,falsefor plain text.SPARKY_FITNESS_EMAIL_USER: Your email username.SPARKY_FITNESS_EMAIL_PASS: Your email password.SPARKY_FITNESS_EMAIL_FROM: The 'from' email address.
Rate Limiting (Server Side)
API keys are rate-limited to prevent abuse. These must be passed to sparkyfitness-server.
SPARKY_FITNESS_API_KEY_RATELIMIT_WINDOW_MS: Time window in milliseconds. Defaults to60000(1 minute).SPARKY_FITNESS_API_KEY_RATELIMIT_MAX_REQUESTS: Maximum number of requests allowed per window. Defaults to100.
Outbound Proxy (Server Side)
Most setups do not need these. They route the server's outbound requests (food providers, fitness integrations, AI providers, etc.) through a forward proxy. This is not how you serve SparkyFitness over HTTPS or behind a reverse proxy — for that (including the HTTPS the mobile app requires), see the Reverse Proxy guide.
The standard docker-compose.yml already passes these to the sparkyfitness-server service; if unset, all requests go direct.
HTTP_PROXY: Proxy URL for outbound plain-HTTP requests (e.g.,http://proxy.example.com:8888).HTTPS_PROXY: Proxy URL for outbound HTTPS requests. Usually still anhttp://URL — it names the proxy to tunnel through, not the proxy's own protocol.NO_PROXY: Comma-separated hosts to reach directly (e.g.,localhost,127.0.0.1,sparkyfitness-garmin). Suffix match; no CIDR ranges. Keep internal Docker services likesparkyfitness-garminhere so container-to-container calls are not sent to the proxy, plus any LAN integrations (Mealie, Tandoor, Ollama, etc.).
SOCKS proxies are not supported.
OIDC Configuration (Server Side)
These variables configure the environment-based OIDC provider and must be passed to the sparkyfitness-server service.
When the following are set, an OIDC provider is created or updated at startup and used with the existing SSO flow.
SPARKY_FITNESS_DISABLE_EMAIL_LOGIN: Set totrueto disable email/password login on the login page (overridden bySPARKY_FITNESS_FORCE_EMAIL_LOGIN).SPARKY_FITNESS_OIDC_AUTH_ENABLED: Set totrueto enable OIDC login, overriding the value from Admin > Authentication Settings.SPARKY_FITNESS_OIDC_ISSUER_URL: Issuer URL (e.g.https://auth.example.com). Discovery URL is derived as issuer +/.well-known/openid-configuration. Required for env provider upsert.SPARKY_FITNESS_OIDC_CLIENT_ID,SPARKY_FITNESS_OIDC_CLIENT_SECRET: Client credentials from your IdP. Required for env provider upsert.SPARKY_FITNESS_OIDC_PROVIDER_SLUG: URL-safe provider id (e.g.authentik). Required for env provider upsert.SPARKY_FITNESS_OIDC_PROVIDER_NAME: Display name for the provider (optional; defaults to slug).SPARKY_FITNESS_OIDC_SCOPE: Space-separated OIDC scopes (optional; defaults toopenid email profile).SPARKY_FITNESS_OIDC_AUTO_REGISTER: Set totrueto automatically create a new user account on first OIDC login (optional; defaults totrue).SPARKY_FITNESS_OIDC_LOGO_URL: URL to a custom logo for the provider (optional).SPARKY_FITNESS_OIDC_DOMAIN: Organization domain for restricted access (optional; defaults toslug.env).SPARKY_FITNESS_OIDC_TOKEN_AUTH_METHOD: Authentication method for the token endpoint (optional; defaults toclient_secret_post).SPARKY_FITNESS_OIDC_ID_TOKEN_SIGNED_ALG: Algorithm used to sign the ID token (optional; defaults toRS256).SPARKY_FITNESS_OIDC_USERINFO_SIGNED_ALG: Algorithm used to sign the UserInfo response (optional; defaults tonone).SPARKY_FITNESS_OIDC_TIMEOUT: Request timeout in milliseconds (optional; defaults to30000).SPARKY_FITNESS_OIDC_AUTO_REDIRECT: Set totrueto allow auto-redirect to the single OIDC provider when email login is disabled.SPARKY_FITNESS_OIDC_ADMIN_GROUP: Group/claim value from your IdP for admin role mapping. Configure your IdP to send this in token claims; it is used to automatically grant admin privileges.ALLOW_PRIVATE_NETWORK_CORS: Set totrueto allow Cross-Origin Resource Sharing (CORS) from private network addresses (e.g.,192.168.x.x,10.x.x.x,127.0.0.1,localhost). This allows standard browser requests from local IPs. Use with caution.SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS: A comma-separated list of additional URLs that Better Auth should trust (e.g.,http://192.168.1.175:8080,http://10.0.0.5:8080). Use this if you are accessing the app from specific local IPs on your network andALLOW_PRIVATE_NETWORK_CORSis enabled.
Garmin Integration
If you require Garmin integration, ensure GARMIN_MICROSERVICE_URL is passed to both the sparkyfitness-server and sparkyfitness-garmin services. The other two variables are for the sparkyfitness-garmin service.
GARMIN_MICROSERVICE_URL: The URL for the Garmin microservice (e.g.,http://sparkyfitness-garmin:8000).GARMIN_SERVICE_PORT: Used for Garmin Connect synchronization. Must matchGARMIN_MICROSERVICE_URL.GARMIN_SERVICE_IS_CN: Set totruefor China region. Defaults tofalse.
MCP Server Configuration
The Model Context Protocol (MCP) server that connects AI assistants to your health data is now served in-process by the main server at POST /mcp. It shares the core database variables with the rest of the server, so no MCP-specific transport configuration is required. See the AI Assistant & MCP Server guide for client setup.
DEV_TOOLS_ENABLED: (Optional) Set totrueto enable the in-process/mcpdeveloper/debugging tools (sparky_inspect_schema,sparky_get_user_info,sparky_get_db_stats). Requires an admin API key, and the tools run with elevated database access that bypasses Row Level Security. Off by default; do not enable in production unless you are actively debugging.
The MCP/API-key request rate is governed by the Rate Limiting variables (SPARKY_FITNESS_API_KEY_RATELIMIT_WINDOW_MS and SPARKY_FITNESS_API_KEY_RATELIMIT_MAX_REQUESTS).
iOS Mobile App Development
These variables configure code signing, bundle identifiers, and shared App Groups for the iOS mobile app (SparkyFitnessMobile). They are only needed during local iOS development or when building for a physical device or simulator.
EXPO_DEV_APPLE_TEAM_ID: The 10-character Apple Developer Team ID used to configure auto-signing in Xcode for dev builds.EXPO_PROD_APPLE_TEAM_ID: The 10-character Apple Developer Team ID used for production builds.EXPO_DEV_BUNDLE_IDENTIFIER: The bundle identifier for the development app (defaults toorg.SparkyApps.SparkyFitnessMobile.dev).WIDGET_BUNDLE_IDENTIFIER: The bundle identifier for the iOS Widget extension (defaults to<EXPO_DEV_BUNDLE_IDENTIFIER>.ExpoWidgetsTarget).IOS_APP_GROUP_DEV: The shared App Group identifier used to pass data between the main app and the widgets during development (defaults togroup.org.SparkyApps.SparkyFitnessMobile.dev).IOS_APP_GROUP_PROD: The shared App Group identifier used to pass data between the main app and the widgets in production (defaults togroup.com.SparkyApps.SparkyFitnessMobile.shared).
File: docs/content/1.install/8.external-database.md
External Database Setup
If you are using your own PostgreSQL instance (e.g., AWS RDS, Azure Database, CloudNativePG, or a local installation) instead of the provided Docker Compose setup, follow these steps to ensure the database is correctly configured.
[!WARNING]
Community Supported Only
External and managed database configurations are not officially tested or supported by the core application maintainers. Use this guide at your own risk.
1. Database and Users
The application uses two database roles:
- SPARKY_FITNESS_DB_USER: Used for migrations and schema management.
- SPARKY_FITNESS_APP_DB_USER: Used by the application components with restricted permissions.
[!IMPORTANT]
The application automatically creates the App User (SPARKY_FITNESS_APP_DB_USER) and grants it all necessary permissions on first startup. The DB User (SPARKY_FITNESS_DB_USER) must haveCREATEROLEto do this.
Option A — Standard Setup (SparkyFitness creates the SPARKY_FITNESS_APP_DB_USER User automatically)
Run the following as a database superuser:
-- 1. Create the Database
CREATE DATABASE sparkyfitness_db;
-- 2. Create the DB Owner user (referenced in .env as SPARKY_FITNESS_DB_USER)
CREATE USER sparky_admin WITH PASSWORD 'your_secure_password';
-- 3. Grant database ownership so sparky_admin can create schemas and tables
ALTER DATABASE sparkyfitness_db OWNER TO sparky_admin;
-- 4. Grant Role Creation privilege
-- Required so the app can automatically create SPARKY_FITNESS_APP_DB_USER
-- on first startup (see utils/dbMigrations.ts)
ALTER USER sparky_admin CREATEROLE;
-- 5. PostgreSQL 15+ only: the default public schema permissions changed in PG 15.
-- Explicitly grant create rights to the owner:
GRANT ALL ON SCHEMA public TO sparky_admin;Option B — Reduced Privilege Setup (you create the SPARKY_FITNESS_APP_DB_USER User manually)
If your environment does not allow CREATEROLE (e.g., strict managed databases), you can pre-create the App User yourself. The application checks whether the role already exists before attempting to create it — if it finds it, CREATE ROLE is skipped entirely and CREATEROLE is not required.
-- 1. Create the Database
CREATE DATABASE sparkyfitness_db;
-- 2. Create the DB Owner user (referenced in .env as SPARKY_FITNESS_DB_USER)
CREATE USER sparky_admin WITH PASSWORD 'your_secure_password';
-- 3. Grant database ownership
ALTER DATABASE sparkyfitness_db OWNER TO sparky_admin;
-- 4. PostgreSQL 15+ only
GRANT ALL ON SCHEMA public TO sparky_admin;
-- 5. Pre-create the App User (referenced in .env as SPARKY_FITNESS_APP_DB_USER)
-- The app detects this role already exists and skips CREATE ROLE,
-- so sparky_admin does NOT need CREATEROLE.
CREATE USER sparky_app WITH PASSWORD 'another_secure_password';Set both users in your .env:
SPARKY_FITNESS_DB_USER=sparky_admin
SPARKY_FITNESS_DB_PASSWORD=your_secure_password
SPARKY_FITNESS_APP_DB_USER=sparky_app
SPARKY_FITNESS_APP_DB_PASSWORD=another_secure_password[!NOTE]
With Option B,sparky_adminstill needs database ownership to run migrations (create tables, schemas, functions, indexes). The only privilege that is no longer required isCREATEROLE.
2. PostgreSQL Extensions
[!NOTE]
No extensions required. As of v0.17.0 release, SparkyFitness no longer depends onuuid-ossp,pgcrypto, orpg_stat_statements.
- UUID generation uses the built-in
gen_random_uuid()(PostgreSQL 13+), which requires no extension.- Encryption is handled entirely in application code (AES-256-GCM via Node.js
crypto), not via database functions.If you are upgrading an existing installation that has these extensions installed, the
20260618000000_remove_superuser_extensions.sqlmigration will attempt to remove them automatically. Non-superuser environments will skip theDROP EXTENSIONstep gracefully — the extensions are unused and harmless if left in place.
3. Row Level Security (RLS)
The sparky_admin user must be the owner of the tables to enable and manage RLS policies. Setting ALTER DATABASE ... OWNER TO sparky_admin ensures that any tables created during migrations are automatically owned by sparky_admin.
4. Environment Configuration
In your .env file, ensure you point to your external database:
SPARKY_FITNESS_DB_HOST=your-db-host
SPARKY_FITNESS_DB_NAME=sparkyfitness_db
SPARKY_FITNESS_DB_USER=sparky_admin
SPARKY_FITNESS_DB_PASSWORD=your_secure_password
SPARKY_FITNESS_DB_PORT=5432
# App user — created automatically (Option A) or pre-created by you (Option B)
SPARKY_FITNESS_APP_DB_USER=sparky_app
SPARKY_FITNESS_APP_DB_PASSWORD=another_secure_password[!IMPORTANT]
SPARKY_FITNESS_APP_DB_USERandSPARKY_FITNESS_APP_DB_PASSWORDare always required in the.envfile — the app uses them for the live query connection pool regardless of which setup option you chose.
- Option A: the app creates this role automatically using these values.
- Option B: the role already exists; the password in
.envmust match the one set when you created it manually.
5. Security Hardening (applies only to Option A)
The CREATEROLE privilege is only required during the initial installation or when a future update needs to create a new specialized database role.
Revoking CREATEROLE
Once the application has successfully started for the first time and you see the log Successfully created role, you can revoke this privilege:
ALTER USER sparky_admin NOCREATEROLE;[!CAUTION]
Potential Issues with NOCREATEROLE
If you revoke this privilege, future application updates that require creating new database roles will fail. If you encounter a "Permission Denied" error during a future upgrade, temporarily re-grantCREATEROLEor manually create the required role as a superuser, then revoke it again.