By default, SparkyFitness ships with a PostgreSQL container inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/CodeWithCJ/SparkyFitness/llms.txt
Use this file to discover all available pages before exploring further.
docker-compose.prod.yml. If you already manage a PostgreSQL server — whether on bare metal, in a VM, or through a managed service such as AWS RDS, Azure Database for PostgreSQL, or CloudNativePG — you can point SparkyFitness at it instead of running the bundled container. This guide explains how to prepare the external database, set the required environment variables, and disable the bundled container.
Requirements
PostgreSQL 15+
SparkyFitness requires PostgreSQL 15 or later. UUID generation uses the built-in
gen_random_uuid() function (available since PostgreSQL 13); no extensions are required as of v0.17.0.Row Level Security
The migration user must own the database tables so it can create and manage Row Level Security (RLS) policies. Setting
ALTER DATABASE ... OWNER TO <user> ensures this automatically.Database Users
SparkyFitness uses two PostgreSQL roles:| Role | Variable | Purpose |
|---|---|---|
| DB User | SPARKY_FITNESS_DB_USER | Runs migrations and schema management. Needs database ownership. |
| App User | SPARKY_FITNESS_APP_DB_USER | Used by the live query connection pool with restricted permissions. Created automatically by the app on first startup (Option A), or pre-created by you (Option B). |
SPARKY_FITNESS_APP_DB_USER and SPARKY_FITNESS_APP_DB_PASSWORD are always required in your .env file, regardless of which option you choose. The app uses this role for all runtime queries.Option A — Standard Setup (App Creates the App User Automatically)
Use this option when your PostgreSQL environment allows theCREATEROLE privilege. Run the following SQL as a database superuser:
Successfully created role once the app user has been created. After that you can optionally revoke CREATEROLE (see Security Hardening below).
Option B — Reduced Privilege Setup (You Pre-create the App User)
Use this option when your environment does not allowCREATEROLE (e.g. strict managed databases such as Azure Database for PostgreSQL Flexible Server). The application detects the pre-existing role and skips CREATE ROLE entirely.
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.PostgreSQL Extensions
No extensions are required as of v0.17.0. 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).
20260618000000_remove_superuser_extensions.sql will attempt to remove them automatically. Non-superuser environments gracefully skip the DROP EXTENSION step — the extensions are unused and harmless if left in place.Environment Variables
Set the following variables in your.env file to point SparkyFitness at your external database:
sparkyfitness-server service in docker-compose.prod.yml:
SPARKY_FITNESS_DB_PORT in docker-compose.prod.yml is hard-coded to 5432 for container-to-container communication. When using an external database, override it in the environment: section or set SPARKY_FITNESS_DB_HOST to your external host and ensure your external server listens on 5432, or update the compose file accordingly.Disable the Bundled Database Container
Once you have configured the external database, comment out or remove thesparkyfitness-db service from your docker-compose.prod.yml so it does not start:
Row Level Security
SparkyFitness uses Row Level Security (RLS) to enforce per-user data isolation at the database level. Thesparky_admin user must be the owner of all tables in order to create and manage RLS policies. Setting ALTER DATABASE sparkyfitness_db OWNER TO sparky_admin (done in the setup steps above) ensures that tables created during migrations are automatically owned by sparky_admin.
Security Hardening
Revoking CREATEROLE after first startup (Option A only)
Revoking CREATEROLE after first startup (Option A only)
The Important: If you revoke
CREATEROLE privilege is only needed during initial installation or when a future update introduces a new database role. Once you see the log message Successfully created role, you can revoke it:CREATEROLE and a future application update requires creating a new role, migrations will fail with a Permission Denied error. If this happens, temporarily re-grant CREATEROLE, run the update, then revoke it again: