SparkyFitness Documentation

SparkyFitness: Built for Families. Powered by AI. Track food, fitness, water, and health — together.

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy SparkyFitness on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name sparkyfitness -p 5432:5432 --restart always postgres:15-alpine
Configured Services & Ports
⚙️ db
image: postgres:15-alpine
🔌 Ports: 5432:5432
docker-compose.yml
yaml (docker-compose.yml)
version: '3.8'

services:
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      POSTGRES_DB: sparkyfitness_db
      POSTGRES_USER: sparky
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    volumes:
      - ./postgresql:/var/lib/postgresql/data

  # sparkyfitness-garmin:
  #   build:
  #     context: ./SparkyFitnessGarmin
  #     dockerfile: Dockerfile.garmin_microservice
  #   ports:
  #     - "8000:8000"
  #   environment:
  #     GARMIN_MICROSERVICE_URL: http://sparkyfitness-garmin:8000
  #   volumes:
  #     - ./SparkyFitnessGarmin:/app
  #   depends_on:
  #     - db

File: README.md

🌐 Language

text
[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:

bash
# 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:8080

Note: 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.

Need Help?

  • Post in Github issues/discussion.
  • For faster response and get help from other community memebers Join our Discord

Star History

Translations

Weblate 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

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:

Installation Steps

  1. Create a new folder and download Docker files:
    Create a new directory for SparkyFitness and navigate into it. Then, download the necessary docker-compose.yml and .env files.

    bash
    mkdir 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.example
  2. Configure Environment Variables:
    The docker-compose.yml file relies on environment variables defined in a .env file.
    Open the downloaded .env file 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.example on GitHub

    For a comprehensive list of all available environment variables and their detailed descriptions, please refer to the Environment Variables documentation.

  3. Start the Application:
    From within the sparkyfitness directory (where docker-compose.yml is located), pull the latest images and start the application services:

    bash
    docker compose pull && docker compose up -d
    • docker compose pull: Downloads the latest Docker images for the services.
    • docker compose up -d: Starts the services defined in the docker-compose.yml file 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 ../postgresql on your host, ensuring your data is not lost if containers are removed.
  • 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-db to ensure the database is running before the server starts.
  • sparkyfitness-frontend:

    • Image: codewithcj/sparkyfitness:latest
    • Purpose: The frontend React application served by Nginx.
    • Ports: Maps host port 3004 to container port 80 (Nginx), making the frontend accessible via http://localhost:3004 (or your configured domain).
    • Dependencies: Depends on sparkyfitness-server to ensure the backend is running.

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.

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:

bash
docker compose stop

To stop and remove all services, networks, and volumes (this will delete your database data!):

bash
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 values

For 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

bash
git clone https://github.com/CodeWithCJ/SparkyFitness.git
cd SparkyFitness

2. Install dependencies

bash
pnpm install

3. Configure environment variables

Copy the example env file to the repo root and fill in your values:

Linux / macOS

bash
cp docker/.env.example .env

Windows (PowerShell)

powershell
Copy-Item docker\.env.example .env

Required 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_HOST in the example file is set to a Docker service name. Change it to localhost for a local install.

4. Set up PostgreSQL

Create the superuser and database that match your .env values.

Linux

bash
sudo -u postgres createuser --pwprompt sparky
sudo -u postgres createdb sparkyfitness_db --owner sparky

macOS (Homebrew) — drop the sudo -u postgres prefix if your current user already has PostgreSQL superuser rights:

bash
createuser --pwprompt sparky
createdb sparkyfitness_db --owner sparky

Windows — open a terminal and use psql as the postgres user (adjust the path to match your PostgreSQL install):

powershell
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

bash
cd SparkyFitnessServer
pnpm start

The 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:

bash
cd SparkyFitnessFrontend
pnpm dev

The 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:8080 for local testing, or your domain like https://fitness.example.com for 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 32
    • node -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 32
    • node -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 to 80 when running as root and 8080 when running as non-root.
  • NGINX_ACCESS_LOG: The access log path for nginx. Defaults to /var/log/nginx/access.log when running as root and /dev/stdout when running as non-root.
  • NGINX_ERROR_LOG: The error log path for nginx. Defaults to /var/log/nginx/error.log when running as root and /dev/stderr when 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 to true to disable email/password login on the login page (overridden by SPARKY_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 to production for 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 to true to 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 to true to 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 to true to 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 to true to 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 to false.
  • 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 and ALLOW_PRIVATE_NETWORK_CORS is enabled.
  • SPARKY_FITNESS_DB_HOST: The hostname of the PostgreSQL database. For Docker Compose, this defaults to sparkyfitness-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 port 5432. Changing this value in .env will not affect container-to-container communication unless you are using an external database server.
    To use this, you must also uncomment the ports section under the sparkyfitness-db service in your docker-compose.yml file.
  • 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 to sparkyfitness-server.
  • SPARKY_FITNESS_SERVER_PORT: The server port (e.g., 3010). Defaults to 3010. 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 to true to make the Swagger API documentation (/api/api-docs) publicly accessible without logging in. Defaults to false.

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: Use true for TLS/SSL, false for 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 to 60000 (1 minute).
  • SPARKY_FITNESS_API_KEY_RATELIMIT_MAX_REQUESTS: Maximum number of requests allowed per window. Defaults to 100.

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 an http:// 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 like sparkyfitness-garmin here 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 to true to disable email/password login on the login page (overridden by SPARKY_FITNESS_FORCE_EMAIL_LOGIN).
  • SPARKY_FITNESS_OIDC_AUTH_ENABLED: Set to true to 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 to openid email profile).
  • SPARKY_FITNESS_OIDC_AUTO_REGISTER: Set to true to automatically create a new user account on first OIDC login (optional; defaults to true).
  • 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 to slug.env).
  • SPARKY_FITNESS_OIDC_TOKEN_AUTH_METHOD: Authentication method for the token endpoint (optional; defaults to client_secret_post).
  • SPARKY_FITNESS_OIDC_ID_TOKEN_SIGNED_ALG: Algorithm used to sign the ID token (optional; defaults to RS256).
  • SPARKY_FITNESS_OIDC_USERINFO_SIGNED_ALG: Algorithm used to sign the UserInfo response (optional; defaults to none).
  • SPARKY_FITNESS_OIDC_TIMEOUT: Request timeout in milliseconds (optional; defaults to 30000).
  • SPARKY_FITNESS_OIDC_AUTO_REDIRECT: Set to true to 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 to true to 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 and ALLOW_PRIVATE_NETWORK_CORS is 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 match GARMIN_MICROSERVICE_URL.
  • GARMIN_SERVICE_IS_CN: Set to true for China region. Defaults to false.

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 to true to enable the in-process /mcp developer/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 to org.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 to group.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 to group.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:

  1. SPARKY_FITNESS_DB_USER: Used for migrations and schema management.
  2. 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 have CREATEROLE to do this.

Option A — Standard Setup (SparkyFitness creates the SPARKY_FITNESS_APP_DB_USER User automatically)

Run the following as a database superuser:

sql
-- 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.

sql
-- 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:

bash
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_admin still needs database ownership to run migrations (create tables, schemas, functions, indexes). The only privilege that is no longer required is CREATEROLE.

2. PostgreSQL Extensions

[!NOTE]
No extensions required. As of v0.17.0 release, SparkyFitness no longer depends on uuid-ossp, pgcrypto, or pg_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.sql migration will attempt to remove them automatically. Non-superuser environments will skip the DROP EXTENSION step 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:

bash
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_USER and SPARKY_FITNESS_APP_DB_PASSWORD are always required in the .env file — 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 .env must 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:

sql
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-grant CREATEROLE or manually create the required role as a superuser, then revoke it again.