Tech Expert & Vibe Coder

With 15+ years of experience, I specialize in self-hosting, AI automation, and Vibe Coding – building applications using AI-powered tools like Google Antigravity, Dyad, and Cline. From homelabs to enterprise solutions.

How to Install SparkyFitness on Proxmox Container Running on Ubuntu Server

Self-Hosting 16 min read Published Apr 25, 2026

SparkyFitness is a self-hosted, privacy-first alternative to MyFitnessPal that runs inside a Proxmox container on Ubuntu Server. It gives you local control over nutrition logs, exercise data, body measurements, goals, reports, and optional AI-powered food logging — all without depending on a hosted fitness platform.

This guide walks through installing SparkyFitness in an Ubuntu LXC container on Proxmox using Docker Compose. We’ll keep Proxmox as the container host, Ubuntu as the application environment, Docker as the runtime, and SparkyFitness as a three-service stack with PostgreSQL, backend, and frontend containers.

Quick Answer: The cleanest way to install SparkyFitness on Proxmox is to create an Ubuntu 24.04 LXC container, enable nesting for Docker, install Docker Engine inside the container, download the official SparkyFitness production Docker Compose file and environment file, edit the required secrets and URLs, then start the stack with docker compose up -d. For a small homelab deployment, 2 CPU cores, 2 GB RAM, and 16–32 GB storage is a practical starting point.

What You’re Installing

SparkyFitness isn’t a single binary. The official project describes it as a self-hosted fitness tracking platform with a backend server, a web frontend, and native mobile app support. The current Docker Compose deployment runs multiple services: PostgreSQL for persistence, a Node.js backend, and a React frontend served through Nginx. You can verify the project details from the official GitHub repository.

The app is useful if you want fitness tracking without sending every meal, weight entry, progress photo, or body metric to a third-party SaaS platform. It supports common fitness-tracking workflows like food logging, exercise tracking, water intake, body measurements, goals, reports, multiple users, and optional integrations.

Proxmox LXC or VM: Which Should You Use?

You can run SparkyFitness in either a full VM or an LXC container. For a lightweight homelab service, an Ubuntu LXC container is attractive because it boots quickly and uses fewer resources than a VM. Proxmox containers are based on LXC, and Proxmox manages them through its own container tooling, as documented in the Proxmox Linux Container documentation.

The tradeoff is Docker inside LXC. It works well for many homelab setups, but it requires nesting support and slightly relaxes the isolation model compared with a plain unprivileged container. If this instance will be exposed to the public internet, used by several people, or treated as sensitive infrastructure, a small Ubuntu VM is still the more conservative choice.

Option Best For Pros Watch Out For
Ubuntu LXC Homelab, private LAN, lightweight deployment Low RAM use, fast boot, easy Proxmox snapshots Docker needs nesting; isolation isn’t as clean as a VM
Ubuntu VM Public-facing or more security-sensitive deployment Cleaner Docker support, stronger isolation boundary Uses more RAM and disk than LXC

For this tutorial, we’ll use an Ubuntu Server LXC container because the target is a Proxmox container deployment. If you already run Docker workloads in LXC, this will feel familiar. If you’re still deciding how to structure Docker on Proxmox, this related guide on Proxmox Docker workloads gives useful context on container-based approaches.

Recommended Resources

SparkyFitness isn’t heavy, but it stores a PostgreSQL database and user uploads, so don’t size the container too aggressively. Start with this baseline and adjust after a week of real usage.

Resource Recommended Starting Point Notes
CPU 2 cores Enough for frontend, backend, and PostgreSQL in a small deployment
RAM 2 GB Use 4 GB if you plan to test AI or several integrations
Disk 16–32 GB Give more space if you expect many uploads or long-term backups
OS Ubuntu 24.04 LTS Docker officially supports Ubuntu Noble 24.04 LTS
Network Static DHCP lease or static IP Makes reverse proxy and mobile app access easier

Step 1: Create the Ubuntu LXC Container in Proxmox

In the Proxmox web interface, create a new container using an Ubuntu 24.04 template. Here’s the GUI path:

  1. Download the template: Go to local or your preferred storage, open CT Templates, and download the Ubuntu 24.04 standard template.
  2. Create the container: Click Create CT, choose a hostname like sparkyfitness, and set a strong root password or SSH key.
  3. Assign resources: Use at least 2 CPU cores, 2 GB RAM, and 16 GB disk.
  4. Configure networking: Use DHCP with a router reservation or assign a static IP directly in Proxmox.
  5. Finish creation: Don’t start the container yet if you still need to enable nesting.

If you prefer the Proxmox shell, the exact command will vary based on your storage name, bridge name, and template path. A typical container creation command looks like this:

pct create 120 local:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst \
  --hostname sparkyfitness \
  --cores 2 \
  --memory 2048 \
  --swap 512 \
  --rootfs local-lvm:20 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --unprivileged 1 \
  --features nesting=1,keyctl=1 \
  --start 1

Replace 120 with your preferred container ID and adjust the template filename to match the one available on your Proxmox node.

Step 2: Enable Nesting for Docker

Docker needs additional container features when it runs inside LXC. If you created the container from the GUI, select the container, go to Options, open Features, and enable Nesting. If your Proxmox version exposes keyctl, enable that too.

From the Proxmox host shell, you can set those options like this:

pct stop 120
pct set 120 -features nesting=1,keyctl=1
pct start 120

Pro Tip: Don’t install Docker directly on the Proxmox host for this setup. Keep Docker inside the Ubuntu container so the SparkyFitness stack, its networks, and its volumes stay isolated from the Proxmox management layer.

Step 3: Update Ubuntu and Install Basic Tools

Enter the container from the Proxmox console or SSH into it. Then update the OS and install the basic packages needed for Docker installation and troubleshooting.

apt update
apt upgrade -y
apt install -y ca-certificates curl gnupg nano openssl lsb-release

Set the timezone if needed:

timedatectl set-timezone Asia/Kolkata
timedatectl

Check that the container has working DNS and internet access:

ping -c 3 github.com
curl -I https://github.com

If DNS fails inside Docker later, the issue may be related to how Ubuntu, systemd-resolved, Docker, and your local DNS server interact. This guide on Docker DNS failures is worth keeping nearby for homelab troubleshooting.

Step 4: Install Docker Engine on Ubuntu

Use Docker’s official apt repository rather than the older distro package. Docker’s own Ubuntu instructions list Ubuntu 24.04 LTS and 22.04 LTS among the supported releases and recommend installing Docker Engine from the official repository. The current steps are available in Docker’s Ubuntu installation documentation.

First, remove conflicting packages if they exist:

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
  apt remove -y $pkg 2>/dev/null || true
done

Add Docker’s official GPG key and apt source:

install -m 0755 -d /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc

chmod a+r /etc/apt/keyrings/docker.asc

cat <<EOF > /etc/apt/sources.list.d/docker.sources
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

apt update

Install Docker Engine, Docker CLI, containerd, Buildx, and the Docker Compose plugin:

apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verify that Docker works inside the LXC container:

docker run hello-world
docker compose version

You should see Docker download and run the test image successfully. If Docker fails with a permissions, overlay, or cgroup error, recheck that the Proxmox container has nesting enabled.

Step 5: Create a Clean Directory for SparkyFitness

Keep application files under /srv/apps instead of scattering Compose files in the root home directory. This makes backups, upgrades, and reverse proxy configuration easier later.

mkdir -p /srv/apps/sparkyfitness
cd /srv/apps/sparkyfitness

Download the official production Compose file and the default environment file from the latest SparkyFitness release:

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

This matches the project’s recommended Docker Compose method, where the official installation flow is to create a folder, download docker-compose.prod.yml and default.env.example, then start the stack with Docker Compose. You can compare this with the SparkyFitness Compose guide.

Step 6: Edit the SparkyFitness Environment File

Open the environment file:

nano .env

At minimum, review and set the following values. The exact names may change as SparkyFitness evolves, so use the downloaded .env file as the source of truth.

SPARKY_FITNESS_DB_NAME=sparkyfitness_db
SPARKY_FITNESS_DB_USER=sparky
SPARKY_FITNESS_DB_PASSWORD=replace_with_a_strong_database_password

SPARKY_FITNESS_APP_DB_USER=sparky_app
SPARKY_FITNESS_APP_DB_PASSWORD=replace_with_a_strong_app_database_password

SPARKY_FITNESS_FRONTEND_URL=http://192.168.1.50:3004

SPARKY_FITNESS_API_ENCRYPTION_KEY=replace_with_64_character_hex_key
BETTER_AUTH_SECRET=replace_with_long_random_secret

DB_PATH=./postgresql
SERVER_BACKUP_PATH=./backup
SERVER_UPLOADS_PATH=./uploads

TZ=Asia/Kolkata
NODE_ENV=production

Generate the encryption key and auth secret with OpenSSL:

openssl rand -hex 32
openssl rand -hex 32

Use the first value for SPARKY_FITNESS_API_ENCRYPTION_KEY and the second for BETTER_AUTH_SECRET.

Important: Don’t casually change BETTER_AUTH_SECRET after users start using two-factor authentication. SparkyFitness documentation warns that this value is tied to authentication security, and changing it later can lock users out of 2FA-protected accounts.

The SparkyFitness environment documentation also notes that mandatory persistent paths include the PostgreSQL database path, server backup path, and uploads path. That matters because your nutrition database and uploaded files should survive container recreation. See the SparkyFitness environment variables page for the full list.

Step 7: Start SparkyFitness with Docker Compose

From inside /srv/apps/sparkyfitness, pull the images and start the stack:

docker compose pull
docker compose up -d

Check the running containers:

docker compose ps

You should see services similar to:

sparkyfitness-db
sparkyfitness-server
sparkyfitness-frontend

Follow the logs during the first startup:

docker compose logs -f

The first run can take a little longer because images are pulled, PostgreSQL initializes, and the backend prepares its database. Once the stack is healthy, open the frontend URL in your browser. If you used the default production Compose mapping documented by SparkyFitness, the frontend is typically available on port 3004:

http://192.168.1.50:3004

Replace 192.168.1.50 with the IP address of your Ubuntu LXC container.

Step 8: Create the First User and Lock Down Signup

After the web interface loads, create your first account. Then decide whether you want open registration enabled. For a private home server, it’s usually better to disable public signup once your admin account exists.

In the .env file, look for signup-related settings and set them according to your preference:

SPARKY_FITNESS_DISABLE_SIGNUP=true
[email protected]

Restart the stack after changing environment values:

docker compose up -d

If you plan to use OIDC with Authentik, Authelia, Keycloak, Google, or another identity provider, configure that only after the basic email login works. SparkyFitness supports OpenID Connect and lets you define issuer URL, client ID, client secret, redirect URI, and related login behavior through the application’s authentication settings.

Step 9: Add a Reverse Proxy with Caddy or Nginx

You can use SparkyFitness directly on http://server-ip:3004, but a reverse proxy is cleaner if you want HTTPS, a friendly domain, or remote mobile app access.

If you already run Caddy on another Proxmox container or VM, add a local DNS record like:

fitness.lan  ->  192.168.1.50

Then configure Caddy to proxy traffic to the SparkyFitness frontend:

fitness.lan {
  reverse_proxy 192.168.1.50:3004
}

If you use a real domain with public DNS and Caddy can complete ACME validation, the same structure works with HTTPS:

fitness.example.com {
  reverse_proxy 192.168.1.50:3004
}

After adding the domain, update SPARKY_FITNESS_FRONTEND_URL in .env:

SPARKY_FITNESS_FRONTEND_URL=https://fitness.example.com

Then recreate the stack:

cd /srv/apps/sparkyfitness
docker compose up -d

The official reverse proxy notes for SparkyFitness mention common proxy headers like Host, X-Real-IP, X-Forwarded-For, and X-Forwarded-Proto. If you use Nginx Proxy Manager or a hand-written Nginx config, make sure those headers are passed correctly. The SparkyFitness reverse proxy page has the project’s reference header example.

If you use Caddy heavily in your homelab, you may also like this related setup on Caddy service discovery, especially if you route several internal services through local DNS.

Step 10: Back Up the Database and Uploads

SparkyFitness stores valuable personal data: meals, body weight, workouts, measurements, reports, and possibly uploaded images. Don’t treat the container as disposable unless you have backups.

At the filesystem level, back up the whole application directory:

tar -czf /root/sparkyfitness-backup-$(date +%F).tar.gz /srv/apps/sparkyfitness

For a more database-aware backup, dump PostgreSQL from the Compose network. First check the database service name:

docker compose ps

Then run a dump command similar to this, adjusting the database name and user to match your .env file:

mkdir -p /srv/backups/sparkyfitness

docker compose exec -T sparkyfitness-db \
  pg_dump -U sparky -d sparkyfitness_db \
  > /srv/backups/sparkyfitness/sparkyfitness-db-$(date +%F).sql

You should also back up uploads and the environment file:

cp .env /srv/backups/sparkyfitness/env-$(date +%F).backup
tar -czf /srv/backups/sparkyfitness/uploads-$(date +%F).tar.gz ./uploads

The SparkyFitness documentation includes manual backup and restore guidance, including warnings that restores can be destructive and that independent backups are still recommended. For a private health-tracking app, follow a 3-2-1 backup approach: three copies, two different media types, and one offsite copy.

Useful Management Commands

Once SparkyFitness is running, these are the commands you’ll use most often.

Check Container Status

cd /srv/apps/sparkyfitness
docker compose ps

View Logs

docker compose logs -f

For only the backend:

docker compose logs -f sparkyfitness-server

Stop the Stack Without Deleting Data

docker compose stop

Start the Stack Again

docker compose up -d

Update SparkyFitness

cd /srv/apps/sparkyfitness
docker compose pull
docker compose up -d
docker image prune -f

Before updating, take a backup. This is especially important because SparkyFitness uses PostgreSQL and may include schema migrations between versions.

Common Problems and Fixes

Docker Won’t Start Inside the LXC Container

If docker run hello-world fails, check that nesting is enabled:

pct config 120 | grep features

You should see something like:

features: keyctl=1,nesting=1

If not, stop the container from the Proxmox host and set the features again:

pct stop 120
pct set 120 -features nesting=1,keyctl=1
pct start 120

The Web UI Doesn’t Load

Check that the frontend container is running and that the port mapping exists:

docker compose ps
ss -tulpn | grep 3004

Then test locally from inside the LXC container:

curl -I http://127.0.0.1:3004

If the local test works but another computer can’t open the page, check Proxmox firewall rules, the LXC IP address, your router firewall, and whether you’re using the correct host port.

Login or API Requests Fail Behind a Reverse Proxy

The most common cause is a mismatch between the browser URL and SPARKY_FITNESS_FRONTEND_URL. If users access the app at https://fitness.example.com, that exact URL should be configured in the environment file.

SPARKY_FITNESS_FRONTEND_URL=https://fitness.example.com

After changing it, restart the stack:

docker compose up -d

Database Data Disappears After Recreating Containers

This usually means the persistent paths weren’t configured correctly or the stack was removed with volumes. Avoid this unless you really want to delete data:

docker compose down -v

Use this instead for normal restarts:

docker compose down
docker compose up -d

Container DNS Works on Ubuntu but Not Inside Docker

Check the container’s resolver:

cat /etc/resolv.conf

If it points to a loopback resolver like 127.0.0.53, Docker containers may not be able to use it as expected. You can define Docker daemon DNS servers explicitly:

mkdir -p /etc/docker

cat <<EOF > /etc/docker/daemon.json
{
  "dns": ["1.1.1.1", "8.8.8.8"]
}
EOF

systemctl restart docker

In a homelab, replace those public resolvers with your Pi-hole, Technitium, or internal DNS server if you want local names like fitness.lan to resolve from containers.

Security Checklist for a Private Fitness App

Because SparkyFitness stores health and fitness data, treat it with more care than a casual dashboard. A few small decisions make a big difference.

  • Use strong secrets: Generate unique values for database passwords, API encryption key, and auth secret.
  • Disable open signup: Turn off registration after creating your account unless you intentionally want family members to register themselves.
  • Keep it private by default: Use LAN-only access, VPN, or Tailscale before exposing it publicly.
  • Use HTTPS: Put Caddy, Nginx, or another reverse proxy in front if accessing from mobile devices or outside the LAN.
  • Back up before updates: Database-backed apps should never be updated without a rollback path.
  • Snapshot carefully: Proxmox snapshots are useful, but application-level PostgreSQL backups are still safer for restore testing.

If you expose self-hosted services publicly, rate limiting and edge controls become important. This related article on Traefik rate limiting covers the same defensive mindset for internet-facing homelab services.

Should You Use the Community Proxmox Helper Script?

SparkyFitness documentation also points Proxmox users to a community-maintained Proxmox VE Helper Script. That can be convenient if you want a quick automated install, but the project notes that the script is community-contributed rather than directly maintained by SparkyFitness.

For a service that stores personal health data, I prefer the manual Docker Compose method shown in this guide. It gives you a clearer understanding of where the Compose file lives, where the database is stored, which environment variables matter, and how to back up or move the deployment later.

Method When to Use It Why
Manual Docker Compose You want control and repeatability Best for learning, backups, customization, and troubleshooting
Community Proxmox script You want a fast test install Convenient, but you should still inspect what it creates
Ubuntu VM You want stronger isolation Best if exposing the app publicly or sharing with multiple users

Final Thoughts

Installing SparkyFitness on Proxmox LXC is a good fit if you want a self-hosted, privacy-first alternative to MyFitnessPal without dedicating a full VM to a small fitness-tracking app. The important parts are enabling Docker-friendly LXC features, installing Docker from the official Ubuntu repository, setting persistent paths correctly, generating stable secrets, and backing up PostgreSQL before every serious change.

Once the basics are running, you can improve the setup with a reverse proxy, HTTPS, local DNS, OIDC login, mobile app access, and scheduled backups. Start simple, confirm the core app works on your LAN, then add the extra layers one at a time.

Previous article

How to Install Dockge on Proxmox Container Running on Ubuntu Server

Next article

How to Install Wallos ‘Open-Source Personal Subscription Tracker’ on Proxmox Container Running on Ubuntu Server

Leave a Comment

Your email address will not be published. Required fields are marked *

Search Articles

Jump to another topic without leaving the reading flow.

Categories

Browse more posts grouped by topic.

About the Author

Vipin PG

Vipin PG

Expert Tech Support & Services

Vipin PG is a software professional with 15+ years of hands-on experience in system infrastructure, browser performance, and AI-powered development. Holding an MCA from Kerala University, he has worked across enterprises in Dubai and Kochi before running his independent tech consultancy. He has written 180+ tutorials on Docker, networking, and system troubleshooting - and he actually runs the setups he writes about.

Stay Updated

Get new posts and practical tech notes in your inbox.

Short, high-signal updates covering self-hosting, automation, AI tooling, and infrastructure fixes.