Removing unused services.
Some checks failed
Auto-Deploy Changed Stacks / deploy (push) Failing after 17s
Some checks failed
Auto-Deploy Changed Stacks / deploy (push) Failing after 17s
This commit is contained in:
parent
9c90b19fc0
commit
550d9b86d8
@ -1,20 +0,0 @@
|
||||
services:
|
||||
apprise-api:
|
||||
image: lscr.io/linuxserver/apprise-api:latest
|
||||
container_name: apprise-api
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/New_York
|
||||
ports:
|
||||
- 8000:8000
|
||||
volumes:
|
||||
- /mnt/appdata/apprise/data:/config
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy-net
|
||||
|
||||
networks:
|
||||
proxy-net:
|
||||
name: proxy-net
|
||||
external: true
|
||||
@ -1,23 +0,0 @@
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
container_name: docker_registry
|
||||
restart: always
|
||||
environment:
|
||||
- REGISTRY_STORAGE_DELETE_ENABLED=true
|
||||
- REGISTRY_HTTP_SECRET=temporary_secret_123
|
||||
volumes:
|
||||
- /mnt/appdata/docker_registry/data:/var/lib/registry
|
||||
networks:
|
||||
- proxy-net
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.registry.rule=Host(`registry.castaldifamily.com`)
|
||||
- traefik.http.routers.registry.entrypoints=websecure
|
||||
- traefik.http.routers.registry.tls.certresolver=cloudflare
|
||||
- traefik.http.services.registry.loadbalancer.server.port=5000
|
||||
|
||||
networks:
|
||||
proxy-net:
|
||||
name: proxy-net
|
||||
external: true
|
||||
@ -1,24 +0,0 @@
|
||||
name: ntfy
|
||||
services:
|
||||
ntfy:
|
||||
image: binwiederhier/ntfy:latest
|
||||
container_name: ntfy
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- serve
|
||||
volumes:
|
||||
- /mnt/appdata/ntfy/data:/var/lib/ntfy
|
||||
- /mnt/appdata/ntfy/server.yml:/etc/ntfy/server.yml:ro
|
||||
networks:
|
||||
- proxy-net
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.ntfy.rule=Host(`ntfy.castaldifamily.com`)"
|
||||
- "traefik.http.routers.ntfy.entrypoints=websecure"
|
||||
- "traefik.http.routers.ntfy.tls=true"
|
||||
- "traefik.http.routers.ntfy.tls.certresolver=cloudflare"
|
||||
- "traefik.http.services.ntfy.loadbalancer.server.port=80"
|
||||
|
||||
networks:
|
||||
proxy-net:
|
||||
external: true
|
||||
@ -1,181 +0,0 @@
|
||||
# SparkyFitness
|
||||
|
||||
**Node:** heimdall
|
||||
**Stack:** `sparkyfitness`
|
||||
**URL:** https://fitness.castaldifamily.com
|
||||
**Version:** v0.16.6.1
|
||||
**Source:** https://github.com/CodeWithCJ/SparkyFitness
|
||||
**Docs:** https://codewithcj.github.io/SparkyFitness/
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
SparkyFitness is a self-hosted, privacy-first fitness and health tracking platform — a full alternative to MyFitnessPal. It stores all data on infrastructure you control with no reliance on third-party services.
|
||||
|
||||
**Core capabilities:**
|
||||
- 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
|
||||
- Native OIDC, TOTP, Passkey, and MFA support
|
||||
- Health platform integrations: Apple Health, Google Health Connect, Fitbit, Withings, Garmin, Polar, Strava
|
||||
- Food database integrations: OpenFoodFacts, USDA, FatSecret, Nutritionix
|
||||
- Recipe app integrations: Mealie, Tandoor
|
||||
- Optional AI chatbot for conversational food/exercise logging (beta)
|
||||
|
||||
**Stack architecture:**
|
||||
|
||||
| Container | Image | Role |
|
||||
|---|---|---|
|
||||
| `sparkyfitness-db` | `postgres:18.3-alpine` | PostgreSQL database |
|
||||
| `sparkyfitness-server` | `codewithcj/sparkyfitness_server:v0.16.6.1` | Node.js backend API |
|
||||
| `sparkyfitness-frontend` | `codewithcj/sparkyfitness:v0.16.6.1` | React frontend (Nginx) |
|
||||
|
||||
---
|
||||
|
||||
## Node
|
||||
|
||||
Runs on **heimdall** — the general-purpose applications node. No GPU is required. Workload is typical of a personal web application.
|
||||
|
||||
---
|
||||
|
||||
## Access
|
||||
|
||||
| Method | Detail |
|
||||
|---|---|
|
||||
| **URL** | https://fitness.castaldifamily.com |
|
||||
| **Auth** | SparkyFitness native auth (TOTP, passkeys, MFA supported) |
|
||||
| **SSO** | Not configured — OIDC with Authentik can be added via env vars (see `.env.example`) |
|
||||
| **Admin panel** | Set `SPARKY_FITNESS_ADMIN_EMAIL` in `.env` to auto-grant admin on first start |
|
||||
|
||||
> ⚠️ Set `SPARKY_FITNESS_DISABLE_SIGNUP=true` in `.env` after creating your initial account to prevent open registration.
|
||||
|
||||
---
|
||||
|
||||
## Appdata
|
||||
|
||||
All persistent data lives under `/mnt/appdata/sparkyfitness/data/` on the NFS share.
|
||||
|
||||
| Path | Contents | Backup Priority |
|
||||
|---|---|---|
|
||||
| `postgresql/` | All user data — nutrition logs, workouts, health metrics, accounts | 🔴 Critical |
|
||||
| `uploads/` | Profile pictures and exercise images | 🟡 Important |
|
||||
| `backup/` | App-generated PostgreSQL exports | 🟢 Nice-to-have |
|
||||
|
||||
Pre-create these directories before first deploy:
|
||||
|
||||
```bash
|
||||
mkdir -p /mnt/appdata/sparkyfitness/data/postgresql
|
||||
mkdir -p /mnt/appdata/sparkyfitness/data/backup
|
||||
mkdir -p /mnt/appdata/sparkyfitness/data/uploads
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Managed via `.env` (git-crypt encrypted). See `.env.example` for the full reference.
|
||||
|
||||
### Required Secrets
|
||||
|
||||
| Variable | Purpose | How to Generate |
|
||||
|---|---|---|
|
||||
| `SPARKY_FITNESS_DB_PASSWORD` | PostgreSQL superuser password | `openssl rand -base64 24` |
|
||||
| `SPARKY_FITNESS_APP_DB_PASSWORD` | App-role DB password (limited privileges) | `openssl rand -base64 24` |
|
||||
| `SPARKY_FITNESS_API_ENCRYPTION_KEY` | 64-char hex key for external integration encryption | `openssl rand -hex 32` |
|
||||
| `BETTER_AUTH_SECRET` | Signs sessions and encrypts TOTP/2FA data | `openssl rand -hex 32` |
|
||||
|
||||
> ⚠️ `SPARKY_FITNESS_API_ENCRYPTION_KEY` — changing this after data is stored invalidates all encrypted external integration credentials.
|
||||
> ⚠️ `BETTER_AUTH_SECRET` — changing this after users have enabled TOTP/2FA locks them out. Do not rotate without disabling 2FA first.
|
||||
|
||||
### Non-Secret Configuration (hardcoded in compose.yaml)
|
||||
|
||||
| Variable | Value | Notes |
|
||||
|---|---|---|
|
||||
| `SPARKY_FITNESS_FRONTEND_URL` | `https://fitness.castaldifamily.com` | Used for CORS and session binding |
|
||||
| `SPARKY_FITNESS_DB_HOST` | `sparkyfitness-db` | Internal Docker service name |
|
||||
| `SPARKY_FITNESS_DB_NAME` | `sparkyfitness_db` | Database name |
|
||||
| `SPARKY_FITNESS_DB_USER` | `sparky` | Superuser for migrations |
|
||||
| `SPARKY_FITNESS_APP_DB_USER` | `sparky_app` | Runtime app user (limited privileges) |
|
||||
| `SPARKY_FITNESS_LOG_LEVEL` | `ERROR` | Use `DEBUG` temporarily for troubleshooting |
|
||||
| `NODE_ENV` | `production` | |
|
||||
| `TZ` | `Etc/UTC` | Adjust if local time is needed for date handling |
|
||||
| `SPARKY_FITNESS_FORCE_EMAIL_LOGIN` | `true` | Failsafe — prevents OIDC misconfiguration lockout |
|
||||
|
||||
---
|
||||
|
||||
## Networking
|
||||
|
||||
| Network | Type | Used By |
|
||||
|---|---|---|
|
||||
| `proxy-net` | External (Traefik) | `sparkyfitness-frontend` only |
|
||||
| `sparkyfitness-network` | Internal bridge | All three containers |
|
||||
|
||||
No host ports are exposed. All external traffic enters via Traefik.
|
||||
|
||||
### Traefik Routing
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Router** | `sparkyfitness` |
|
||||
| **Rule** | `Host(\`fitness.castaldifamily.com\`)` |
|
||||
| **Entrypoint** | `websecure` (HTTPS) |
|
||||
| **TLS** | Cloudflare cert resolver |
|
||||
| **Middleware** | `security-headers@file` |
|
||||
| **Backend port** | `80` (Nginx inside `sparkyfitness-frontend`) |
|
||||
|
||||
The frontend Nginx container internally proxies API requests to `sparkyfitness-server:3010` over `sparkyfitness-network`. No separate Traefik route is needed for the API.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Dependency | Type | Notes |
|
||||
|---|---|---|
|
||||
| PostgreSQL 18.3-alpine | Bundled | Self-contained — no shared DB instance |
|
||||
| Traefik | External (core stack) | Must be running on `proxy-net` |
|
||||
| Cloudflare DNS | External | Required for TLS cert resolver |
|
||||
|
||||
No Redis, GPU, or kernel module dependencies.
|
||||
|
||||
---
|
||||
|
||||
## Backup & Recovery
|
||||
|
||||
### What to Back Up
|
||||
|
||||
The `postgresql/` directory is the **single source of truth** for all user data. This must be in the backup rotation before going live.
|
||||
|
||||
```
|
||||
/mnt/appdata/sparkyfitness/data/postgresql/ ← Critical
|
||||
/mnt/appdata/sparkyfitness/data/uploads/ ← Important
|
||||
```
|
||||
|
||||
### Restore Steps
|
||||
|
||||
1. Stop the stack: `docker compose down`
|
||||
2. Restore the PostgreSQL data directory to `/mnt/appdata/sparkyfitness/data/postgresql/`
|
||||
3. Restore uploads to `/mnt/appdata/sparkyfitness/data/uploads/`
|
||||
4. Redeploy: `docker compose up -d`
|
||||
5. Verify the DB is healthy: `docker compose logs sparkyfitness-db`
|
||||
|
||||
### Upgrading
|
||||
|
||||
> ⚠️ Auto-updating containers is **not recommended** by the maintainer. Watchtower should be excluded from this stack.
|
||||
|
||||
1. Review release notes at https://github.com/CodeWithCJ/SparkyFitness/releases
|
||||
2. Take a backup of `postgresql/`
|
||||
3. Update image tags in `compose.yaml`
|
||||
4. Commit and push — Komodo will redeploy via webhook
|
||||
5. Check logs: `docker compose logs --tail=50`
|
||||
|
||||
---
|
||||
|
||||
## Known Issues / Notes
|
||||
|
||||
- **Garmin microservice** (`sparkyfitness-garmin`) is still in development upstream. It is commented out of the compose file intentionally. Do not enable until the maintainer marks it stable.
|
||||
- **Auto-update warning**: The maintainer explicitly warns against automated container updates between releases. Ensure Watchtower is not targeting this stack.
|
||||
- **Postgres upgrade notice**: The upstream release notes flag a forthcoming mandatory Postgres upgrade. Monitor release notes and follow the [official Postgres upgrade guide](https://codewithcj.github.io/SparkyFitness/install/postgres-upgrade) when the time comes.
|
||||
- **AI chatbot** is in beta — expect potential bugs if enabled.
|
||||
- **Family & Friends access** is in beta — expect potential bugs if enabled.
|
||||
@ -1,149 +0,0 @@
|
||||
x-info:
|
||||
repo: https://github.com/CodeWithCJ/SparkyFitness
|
||||
releases: https://github.com/CodeWithCJ/SparkyFitness/releases
|
||||
documentation: https://codewithcj.github.io/SparkyFitness/
|
||||
|
||||
# nodes/heimdall/sparkyfitness/compose.yaml
|
||||
# Deployed via Komodo | Managed by GitOps
|
||||
# Service: sparkyfitness
|
||||
# Source: https://github.com/CodeWithCJ/SparkyFitness
|
||||
|
||||
networks:
|
||||
proxy-net:
|
||||
external: true
|
||||
sparkyfitness-network:
|
||||
driver: bridge
|
||||
|
||||
services:
|
||||
|
||||
# ── Database ────────────────────────────────────────────────────────────────
|
||||
sparkyfitness-db:
|
||||
image: postgres:18.3-alpine
|
||||
container_name: sparkyfitness-db
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- sparkyfitness-network
|
||||
environment:
|
||||
POSTGRES_DB: sparkyfitness_db
|
||||
POSTGRES_USER: sparky
|
||||
POSTGRES_PASSWORD: "${SPARKY_FITNESS_DB_PASSWORD}"
|
||||
PUID: 1000
|
||||
GUID: 1000
|
||||
volumes:
|
||||
- /mnt/appdata/sparkyfitness/data/postgresql:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U sparky -d sparkyfitness_db"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "1.0"
|
||||
memory: 512M
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ── Backend Server ───────────────────────────────────────────────────────────
|
||||
sparkyfitness-server:
|
||||
image: codewithcj/sparkyfitness_server:v0.16.6.1
|
||||
container_name: sparkyfitness-server
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- sparkyfitness-network
|
||||
environment:
|
||||
# Database connection
|
||||
SPARKY_FITNESS_DB_HOST: sparkyfitness-db
|
||||
SPARKY_FITNESS_DB_PORT: 5432
|
||||
SPARKY_FITNESS_DB_NAME: sparkyfitness_db
|
||||
SPARKY_FITNESS_DB_USER: sparky
|
||||
SPARKY_FITNESS_DB_PASSWORD: "${SPARKY_FITNESS_DB_PASSWORD}"
|
||||
SPARKY_FITNESS_APP_DB_USER: sparky_app
|
||||
SPARKY_FITNESS_APP_DB_PASSWORD: "${SPARKY_FITNESS_APP_DB_PASSWORD}"
|
||||
# Security — values sourced from .env (git-crypt)
|
||||
SPARKY_FITNESS_API_ENCRYPTION_KEY: "${SPARKY_FITNESS_API_ENCRYPTION_KEY}"
|
||||
BETTER_AUTH_SECRET: "${BETTER_AUTH_SECRET}"
|
||||
# Application
|
||||
SPARKY_FITNESS_FRONTEND_URL: "https://fitness.castaldifamily.com"
|
||||
SPARKY_FITNESS_LOG_LEVEL: ERROR
|
||||
NODE_ENV: production
|
||||
TZ: Etc/UTC
|
||||
SPARKY_FITNESS_DISABLE_SIGNUP: "false"
|
||||
SPARKY_FITNESS_FORCE_EMAIL_LOGIN: "true"
|
||||
ALLOW_PRIVATE_NETWORK_CORS: "false"
|
||||
PUID: 1000
|
||||
GUID: 1000
|
||||
# Garmin microservice (disabled — service not yet stable)
|
||||
# GARMIN_MICROSERVICE_URL: http://sparkyfitness-garmin:8000
|
||||
volumes:
|
||||
- /mnt/appdata/sparkyfitness/data/backup:/app/SparkyFitnessServer/backup
|
||||
- /mnt/appdata/sparkyfitness/data/uploads:/app/SparkyFitnessServer/uploads
|
||||
depends_on:
|
||||
sparkyfitness-db:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -qO- http://localhost:3010/ 2>&1 | grep -q '.' || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "1.5"
|
||||
memory: 512M
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ── Frontend ─────────────────────────────────────────────────────────────────
|
||||
sparkyfitness-frontend:
|
||||
image: codewithcj/sparkyfitness:v0.16.6.1
|
||||
container_name: sparkyfitness-frontend
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxy-net
|
||||
- sparkyfitness-network
|
||||
environment:
|
||||
SPARKY_FITNESS_FRONTEND_URL: "https://fitness.castaldifamily.com"
|
||||
SPARKY_FITNESS_SERVER_HOST: sparkyfitness-server
|
||||
SPARKY_FITNESS_SERVER_PORT: 3010
|
||||
PUID: 1000
|
||||
GUID: 1000
|
||||
depends_on:
|
||||
sparkyfitness-server:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -q --spider http://localhost:80/ || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
labels:
|
||||
# Enable Traefik
|
||||
- "traefik.enable=true"
|
||||
# HTTPS Router
|
||||
- "traefik.http.routers.sparkyfitness.rule=Host(`fitness.castaldifamily.com`)"
|
||||
- "traefik.http.routers.sparkyfitness.entrypoints=websecure"
|
||||
- "traefik.http.routers.sparkyfitness.tls=true"
|
||||
- "traefik.http.routers.sparkyfitness.tls.certresolver=cloudflare"
|
||||
- "traefik.http.routers.sparkyfitness.service=sparkyfitness"
|
||||
- "traefik.http.routers.sparkyfitness.middlewares=security-headers@file"
|
||||
# Service definition
|
||||
- "traefik.http.services.sparkyfitness.loadbalancer.server.port=80"
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "0.5"
|
||||
memory: 128M
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
@ -1,33 +0,0 @@
|
||||
###############################################################
|
||||
# Networks
|
||||
###############################################################
|
||||
networks:
|
||||
proxy-net:
|
||||
name: proxy-net
|
||||
external: true
|
||||
|
||||
###############################################################
|
||||
# Services
|
||||
###############################################################
|
||||
services:
|
||||
weatherchannel:
|
||||
image: ghcr.io/mwood77/ws4kp-international
|
||||
container_name: weatherchannel
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: wget --no-verbose --tries=1 --spider http://localhost:8080/ || exit 1
|
||||
start_period: 20s
|
||||
timeout: 3s
|
||||
interval: 15s
|
||||
retries: 3
|
||||
networks:
|
||||
- proxy-net
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.weatherchannel.entrypoints=websecure"
|
||||
- "traefik.http.routers.weatherchannel.rule=Host(`weather.castaldifamily.com`)"
|
||||
- "traefik.http.routers.weatherchannel.tls=true"
|
||||
- "traefik.http.routers.weatherchannel.tls.certresolver=cloudflare"
|
||||
- "traefik.http.routers.weatherchannel.service=weatherchannel"
|
||||
- "traefik.http.services.weatherchannel.loadbalancer.server.port=8080"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user