---
title: "Deploy wger"
description: "Workout, nutrition and body weight tracker with a REST API"
category: "Other"
url: https://railway.com/deploy/wger-fitness
---

# Deploy wger

Workout, nutrition and body weight tracker with a REST API

**[Deploy wger on Railway](https://railway.com/template/wger-fitness)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/wger-fitness/manifest.json

- **Creator:** A3A
- **Category:** Other
- **Total deploys:** 1

## Template content

### wger https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/wger.svg

- **Source:** https://github.com/gridalpha/wger-railway
- **Health check:** /api/v2/version/
- **Public domain:** Yes

### celery-worker https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/celery.png

- **Source:** https://github.com/gridalpha/wger-railway
- **Health check:** /healthz

### Redis https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/redis.svg

- **Image:** redis:8.2
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ && exec docker-entrypoint.sh redis-server --requirepass $REDIS_PASSWORD --save 60 1 --dir $RAILWAY_VOLUME_MOUNT_PATH"`

### Postgres https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### celery-beat https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/celery.png

- **Source:** https://github.com/gridalpha/wger-railway
- **Health check:** /healthz

## Buckets

- **wger-media**

## Documentation

# Deploy and Host wger on Railway

Self-host wger to keep your training log, nutrition diary and body measurements on infrastructure you control. wger is an AGPL fitness manager for lifters tracking their progression, coaches running a small gym, and anyone who would rather not hand a year of body-weight data to an app that might shut down. It ships a workout planner with 800+ exercises, a nutrition diary backed by Open Food Facts, measurement charts, gym management, a REST API, and official Android and iOS apps.

Deploy wger on Railway and this template builds the production shape upstream documents, not a single container. The **wger** service is the only public one: Django under gunicorn, with Caddy in front serving static files and routing media. **celery-worker** runs the background jobs and **celery-beat** schedules them. **Postgres** holds every workout, meal and measurement, **Redis** is Django's cache and the Celery broker, and the **wger-media** bucket holds photos, exercise images and videos so the web and worker tiers share one store.

![Diagram of the wger, Celery and datastore services on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789279327/wger-architecture.webp)

## Getting Started with wger on Railway

Set `WGER_ADMIN_PASSWORD` before you deploy — it is the `admin` account's password, replacing the `adminadmin` default wger's bootstrap fixture creates. The first boot loads fixtures, migrates and collects static files, so give it a couple of minutes.

Open the public URL and sign in at `/en/user/login` as `admin`. To confirm the deployment end to end: open **Training → Routines**, create a routine, add a training day, then use the exercise search to add movements with sets, reps and weight. The search hitting the database proves the fixtures loaded; saving proves Postgres is writable. Add a body-weight entry from the dashboard's Weight card — after two or three the chart, moving average and trend line render. Then upload a photo under **Body weight → Gallery**: that round-trips through the bucket, so if it renders, media storage is wired correctly.

Self-registration is closed by default. Set `ALLOW_REGISTRATION` to `True` on the **wger** service to let visitors create accounts, or add members yourself from the gym-management screens under the Administrator menu, which is the safer default on a public URL.

![wger dashboard showing a routine and a body weight trend chart](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789279330/wger-dashboard.webp)
![wger routine detail listing four exercises with sets and weights](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789279331/wger-routine-detail.webp)
![wger body weight chart with trend line and the entry table](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789279333/wger-body-weight.webp)

## About Hosting wger

wger is a Django application developed in the open since 2012. It covers the whole loop a lifter or a small gym needs: plan a routine, log what you lifted and ate, weigh in, watch the numbers move. Self-hosting wins when the data matters more than the convenience — your history stays in a database you can dump.

Key features:

- Routine builder with progression rules, supersets, rest days and per-iteration sets
- 800+ exercises with muscle diagrams, images and videos from a public instance
- Nutrition diary with a barcode scanner and Open Food Facts lookup
- Body weight and custom measurements with trend lines
- Gym management: members, trainers, per-member configuration
- REST API with JWT auth, used by the official mobile apps

The Railway topology separates the tiers so one never blocks the other. Django serves requests; Celery does the long work — the catalogue sync alone pulls hundreds of images — so it never stalls a page load. Media goes to object storage rather than a disk, which is what lets the web and worker services write to the same place.

## Why Deploy wger on Railway

Railway removes the parts of self-hosting that have nothing to do with fitness tracking:

- Postgres, Redis and object storage provisioned and wired up for you
- HTTPS and a public domain from the first deploy, no reverse proxy to configure
- Worker and scheduler are their own services, so you scale them separately
- Private networking keeps the database, cache and workers off the internet
- Rolling deploys and per-service logs, no server to patch

## Common Use Cases

- **Personal training log** — years of workouts, weigh-ins and progress photos, with the mobile app syncing to your own domain.
- **Small gym or PT studio** — members, trainers and per-member routines, with accounts created by staff.
- **Coaching with data you own** — pull the REST API into your dashboards, or read raw tables out of Postgres.
- **Nutrition tracking with no subscription** — ingredient database and barcode scanner, no monthly cost, no ads.

## Dependencies for wger

- **wger** — `docker.io/wger/server:2.7`, built from [gridalpha/wger-railway](https://github.com/gridalpha/wger-railway). Django + gunicorn behind Caddy, which serves static files and signs reads from the media bucket.
- **celery-worker** — same image, running `celery worker`: catalogue and ingredient syncs, image downloads, cache warming.
- **celery-beat** — same image, running `celery beat`. Enqueues the recurring jobs; without it no sync ever fires.
- **Postgres 18** — users, routines, workout logs, meals and measurements.
- **Redis 8.2** — Django's cache plus the Celery broker and result backend.
- **wger-media bucket** — gallery photos, exercise images and videos.

### Environment Variables Reference

| Variable | Purpose |
|---|---|
| `WGER_ADMIN_PASSWORD` | Password for `admin`, replacing the shipped default |
| `SECRET_KEY` | Django signing key; changing it invalidates every session |
| `ALLOW_REGISTRATION` | `False` by default; `True` opens public sign-up |
| `SYNC_EXERCISES_CELERY` | Weekly catalogue sync from `WGER_INSTANCE` |
| `SYNC_INGREDIENTS_CELERY` | Off by default; the bulk dump is 408 MB compressed |
| `JWT_PRIVATE_KEY` / `JWT_PUBLIC_KEY` | Mobile-app token signing pair, generated at first boot |

### Deployment Dependencies

- Source repository: [gridalpha/wger-railway](https://github.com/gridalpha/wger-railway)
- Upstream: [wger-project/wger](https://github.com/wger-project/wger) and [docker.io/wger/server](https://hub.docker.com/r/wger/server)
- Documentation: [wger.readthedocs.io](https://wger.readthedocs.io)

## Hardware Requirements for Self-Hosting wger

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU across all services | 2 vCPU |
| RAM | 1 GB total | 2 GB (web 768 MB, worker 512 MB, beat 256 MB) |
| Storage | 1 GB Postgres | 5 GB Postgres, plus object storage that grows with uploads |
| Runtime | Postgres 13+, Redis 6+ | Postgres 18, Redis 8 |

Enabling the bulk ingredient sync changes this entirely — the compressed dump is 408 MB and expands to gigabytes of rows, so raise the database first.

## Self-Hosting wger with Docker

Upstream publishes a Compose stack. Clone and start it:

```
git clone https://github.com/wger-project/docker.git wger
cd wger
docker compose up -d
```

Edit `config/prod.env` before the first start: `SECRET_KEY`, `SITE_URL` and a fresh JWT keypair from `./manage.py generate-jwt-keys`. To keep uploads in object storage rather than a local volume, set the S3 block in the same file:

```
USE_S3_MEDIA_FILES=True
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_STORAGE_BUCKET_NAME=your-bucket
AWS_S3_REGION_NAME=auto
AWS_S3_ENDPOINT_URL=https://your-endpoint
AWS_S3_DOMAIN=your-endpoint-host
```

wger builds unsigned media URLs, so a bucket configured this way must be browser-readable — public-read, or something in front that signs the reads, which is what this Railway template does for you.

## Is wger Free to Self-Host?

wger is free and open source under the AGPL-3.0: no paid tier, no licence key, no vendor to pay. On Railway you pay only for the compute, database and object storage the deployment uses — small for a personal instance, scaling with members and uploads.

## FAQ

**What is wger?**
An open-source workout, nutrition and body-weight tracker you run yourself: routine planning, workout logging, a nutrition diary with barcode scanning, body measurements and gym member management, plus a REST API and official mobile apps.

**What does this Railway template deploy?**
Six pieces: the wger web app, a Celery worker, a Celery scheduler, Postgres, Redis and an object-storage bucket. Only the web service gets a public URL; the rest stay private.

**Why does the template include Redis and a separate worker service?**
Catalogue syncs, ingredient fetches and image downloads are slow background jobs. Redis carries the queue, the worker runs the jobs, the scheduler enqueues the recurring ones. Redis is also Django's cache, which the exercise API leans on.

**Why is uploaded media stored in a bucket instead of a disk?**
Both the web service and the worker write media — you upload gallery photos, the worker downloads exercise images. A shared object store lets both write to one place, and uploads survive every redeploy.

**How do I connect the wger mobile app to my self-hosted server?**
In the app's server settings enter your deployment's URL instead of wger.de, then sign in. Token auth uses the RS256 keypair generated on first boot, so nothing else is needed.

**How do I get the full exercise database with images?**
The catalogue sync runs weekly once the worker and scheduler are up, pulling from the instance in `WGER_INSTANCE`. To fill it now, run `manage.py sync-exercises` then `download-exercise-images` on the wger service.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/wger-fitness
