homelab/documentation/KBAs/KBA-002-SparkyFitness-Deployment.md
Nathan 54a885120d feat(sparkyfitness): add sparkyfitness stack to heimdall
- Compose file with pinned images (v0.16.6.1), healthchecks, Traefik routing
- .env.example with all required variables and generation commands
- README covering access, appdata, backup scope, upgrade procedure
- KBA-002: deployment reference with verification and rollback steps
- repo-deploy.prompt.md: reusable end-to-end deployment workflow prompt
- Session snapshot 2026-05-10

Source: https://github.com/CodeWithCJ/SparkyFitness
2026-05-10 21:58:38 -04:00

221 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# KBA-002: SparkyFitness — Initial Deployment on Heimdall
**Status:** Active
**Created:** May 10, 2026
**Last Updated:** May 10, 2026
**Affected Systems:** heimdall, Komodo, Traefik
**Severity:** Informational
---
## Summary
Reference article for deploying SparkyFitness (self-hosted fitness tracker) on the heimdall node. Covers pre-deployment checklist, secret generation, first-boot sequence, and verification steps.
---
## Use Case
You want to deploy SparkyFitness for the first time, or you are recovering from a failed deployment or data loss event and need to redeploy from scratch.
---
## Prerequisites
### Access Required
- [ ] SSH access to `heimdall`
- [ ] Gitea access: `git.castaldifamily.com`
- [ ] Komodo UI access: `komodo.castaldifamily.com`
- [ ] NFS share mounted and writable at `/mnt/appdata/` on heimdall
### Files in Repo
Confirm these files exist in `nodes/heimdall/sparkyfitness/` on `main`:
- [ ] `compose.yaml`
- [ ] `.env.example`
- [ ] `README.md`
---
## Resolution / Deployment Steps
### Step 1 — Generate Secrets
On any machine with `openssl` available, generate the four required secrets:
```bash
# API encryption key — SAVE THIS. Do not rotate after data is stored.
openssl rand -hex 32
# Better Auth secret — SAVE THIS. Do not rotate after users enable 2FA.
openssl rand -hex 32
# Database superuser password
openssl rand -base64 24
# Application user password
openssl rand -base64 24
```
Store these immediately in the git-crypt-encrypted `.env` file at:
```
nodes/heimdall/sparkyfitness/.env
```
Using `.env.example` as the template:
```bash
cp nodes/heimdall/sparkyfitness/.env.example nodes/heimdall/sparkyfitness/.env
# Edit .env and fill in all four required secret values
```
> ⚠️ Confirm `.gitattributes` marks `nodes/heimdall/sparkyfitness/.env` as a git-crypt file before committing.
### Step 2 — Create Appdata Directories
SSH into heimdall and pre-create the required directories:
```bash
ssh heimdall
mkdir -p /mnt/appdata/sparkyfitness/data/postgresql
mkdir -p /mnt/appdata/sparkyfitness/data/backup
mkdir -p /mnt/appdata/sparkyfitness/data/uploads
```
> PostgreSQL will fail to initialize if `postgresql/` does not exist or has incorrect ownership. Docker will create the directory automatically, but pre-creating it ensures the NFS mount is active and writable before the container starts.
### Step 3 — Commit and Push
```bash
git add nodes/heimdall/sparkyfitness/
git commit -m "feat(sparkyfitness): add sparkyfitness stack to heimdall
- Compose file with pinned images (v0.16.6.1), healthchecks, Traefik routing
- .env.example with all required variables documented
- README covering access, appdata, backup scope
Source: https://github.com/CodeWithCJ/SparkyFitness"
git push origin main
```
### Step 4 — Create Komodo Stack
1. Open Komodo UI → **Stacks****New Stack**
2. Configure:
| Field | Value |
|---|---|
| **Name** | `sparkyfitness` |
| **Server** | `heimdall` |
| **Source** | Git Repo |
| **Repo** | `homelab` |
| **Branch** | `main` |
| **Run Directory** | `nodes/heimdall/sparkyfitness` |
| **File Paths** | *(leave blank — uses `compose.yaml` by default)* |
| **Webhook** | Enable — trigger on push to `main` |
| **Auto Update** | ❌ Disabled |
3. Click **Deploy**
### Step 5 — First Boot Sequence
The startup order is enforced by `depends_on` + `healthcheck` conditions:
```
sparkyfitness-db (healthy) → sparkyfitness-server (healthy) → sparkyfitness-frontend
```
Expected timeline:
- `sparkyfitness-db`: healthy within ~30 seconds
- `sparkyfitness-server`: ~6090 seconds (runs DB migrations on first boot)
- `sparkyfitness-frontend`: starts once server is healthy
Monitor startup:
```bash
ssh heimdall
docker compose -f /etc/komodo/stacks/sparkyfitness/compose.yaml logs -f
```
### Step 6 — Set Admin Account
If `SPARKY_FITNESS_ADMIN_EMAIL` is set in `.env`, the first user with that email will be automatically granted admin on server startup.
Alternatively, register via the UI at https://fitness.castaldifamily.com, then promote from the Admin panel.
> After creating your account, set `SPARKY_FITNESS_DISABLE_SIGNUP=true` in `.env` to close open registration. Redeploy to apply.
---
## Verification
Run through the following checks after deployment:
### Container Health
```bash
docker ps --filter "name=sparkyfitness"
# All three containers should show: Up X minutes (healthy)
```
### Log Check
```bash
docker compose logs --tail=50 sparkyfitness-server
# Should show: server started, DB migrations complete, no ERRORs
```
### UI Access
- Open https://fitness.castaldifamily.com in a browser
- Confirm: HTTPS with valid certificate, no browser errors
- Confirm: Login page loads
### Traefik Routing
- Open Traefik dashboard → confirm `sparkyfitness` router is active and green
- Confirm TLS cert is issued via Cloudflare resolver
### Restart Resilience
```bash
docker restart sparkyfitness-frontend
# Wait 30s, then confirm the UI is still accessible
```
---
## Rollback
If deployment fails and you need to revert:
1. Stop the stack in Komodo: **Stack → Stop**
2. Remove containers: `docker compose down` on heimdall
3. The `postgresql/` data directory is untouched by `docker compose down` (bind mount, not a volume)
4. Revert the compose file changes in Git and push — Komodo will redeploy the previous version
> ⚠️ `docker compose down -v` would only affect named volumes. Since we use bind mounts, data in `/mnt/appdata/sparkyfitness/data/` is always preserved unless you manually delete it.
---
## Related Resources
- [SparkyFitness README](../../nodes/heimdall/sparkyfitness/README.md)
- [Upstream GitHub](https://github.com/CodeWithCJ/SparkyFitness)
- [Official Docs](https://codewithcj.github.io/SparkyFitness/)
- [Docker Compose Install Guide](https://codewithcj.github.io/SparkyFitness/install/docker-compose)
- [Environment Variables Reference](https://codewithcj.github.io/SparkyFitness/install/environment-variables)
- [Postgres Upgrade Guide](https://codewithcj.github.io/SparkyFitness/install/postgres-upgrade)
- [KBA-001: Komodo GitOps Stack Deployment Failures](KBA-001-Komodo-GitOps-Stack-Deployment-Failures.md)
---
## Revision History
| Date | Author | Change |
|---|---|---|
| 2026-05-10 | Nathan Castaldi | Initial deployment — SparkyFitness v0.16.6.1 on heimdall |