Railway

Deploy SparkyFitness v1.6.1 | MyFitnessPal Alternative, Not Claimable by Strangers

MyFitnessPal alternative. Your admin account is seeded, signup closed.

Deploy SparkyFitness v1.6.1 | MyFitnessPal Alternative, Not Claimable by Strangers

Just deployed

/var/lib/postgresql

Deploy and Host SparkyFitness on Railway

SparkyFitness is a self-hosted calorie and fitness tracker — a MyFitnessPal alternative you own. Log food against a searchable database, track exercise, water, weight and body measurements, keep progress photos, follow custom nutrient goals, and read it all back as charts. It also ships an MCP server, so an AI assistant can log your meals for you.

This template deploys it with your account already created and signup closed. Upstream leaves registration open and grants administrator to the first account created, so on a public URL the first stranger to load the page owns the instance. Here the admin account is written before the server ever binds the port it keeps, from a password Railway generates for this deployment.

About Hosting SparkyFitness

Three services: the React frontend behind nginx, the Node API server, and PostgreSQL. The frontend is the only public one — the API is reached over Railway's private network, so there is no second public domain and no request leaving the platform to come back in through the edge. Food, exercise and measurement history live in PostgreSQL on a volume; profile pictures, exercise images, check-in photos and database backups live on the API server's own volume.

First boot runs a hundred-odd SQL migrations, creates the restricted application role, applies row-level security policies and seeds your account, then starts serving. Redeploys skip straight to the last step.

Why Deploy SparkyFitness on Railway?

A nutrition tracker is the kind of thing you use every day for years, from a phone, away from home — which means it wants a real domain and a certificate, not a port on a NAS. Railway gives it that plus a managed Postgres, a persistent disk and private networking between the two, with no reverse proxy to write.

The same convenience is the risk this template is built around: Railway publishes the URL the moment the deploy goes green, so an instance that ships with open registration is claimable before you have finished reading the deploy log.

Common Use Cases

  • Calorie, macro and micronutrient tracking with your own food database, no ads and no export paywall.
  • Weight, body-measurement and progress-photo tracking kept off other people's servers.
  • An MCP endpoint so an AI assistant can log meals, read today's totals and answer questions about your own data.

Dependencies for SparkyFitness Hosting

  • PostgreSQL 18 (included in this template).
  • Two persistent volumes: one for the database, one for uploads and backups.

Deployment Dependencies

  • Upstream project: https://github.com/CodeWithCJ/SparkyFitness (pinned here to v1.6.1)
  • Upstream images: codewithcj/sparkyfitness, codewithcj/sparkyfitness_server
  • This template's images: ghcr.io/bon5co/sparkyfitness-railway-web and -server (source)
  • License: GPL-3.0

Implementation Details

Your account exists before the URL does. better-auth gives role: admin to the first account created, and SPARKY_FITNESS_DISABLE_SIGNUP is unset upstream. Measured against codewithcj/sparkyfitness_server:v1.6.1 with no wrapper: an anonymous POST /api/auth/sign-up/email returned 200 with "role":"admin". This template's entrypoint creates your account on a throwaway listener, then re-execs the server with signup disabled. On the live deploy the same anonymous request returns 400 "Signups are currently disabled by the administrator.", the generated password logs in 200, and a wrong password returns 401. Seeding is idempotent — a redeploy finds the account and skips it.

Sign in with admin@example.com and the generated SPARKY_FITNESS_ADMIN_PASSWORD, then change both from the profile page. Set SPARKY_FITNESS_DISABLE_SIGNUP=false if you want open registration back.

The login rate limiter counts each client, not the whole internet. Upstream keys nginx's limit_req_zone on $binary_remote_addr, which behind Railway's edge is the same handful of addresses for every visitor, so the 5r/s auth limit is one shared bucket. Measured: 30 requests from 30 distinct clients returned 18 × 503 on the stock image and 0 here, while 30 requests from a single client still return 18 × 503.

Uploads survive redeploys. Profile pictures, exercise images and check-in photos default to /app/SparkyFitnessServer/uploads — the ephemeral container layer. Here they and the backup directory are on the volume.

The frontend follows Railway's injected $PORT, because Railway's healthcheck dials the injected port rather than the domain's target port, and it resolves the API's private address per request rather than once at startup, so a redeployed API service does not leave the frontend dialling an address that has moved.

The deploy form asks for nothing. Every literal is baked into the images; only generated secrets and cross-service references are template variables, so there are no blank required fields to fill in.


Template Content

More templates in this category

View Template
Rocky Linux
[Jul'26] Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
37
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
51