π First beta release is live β
v0.1.0-beta.1. Workouts, programs, gym mode, dashboard, weight, and the new nutrition tracker are all in. Pin this tag for a stable self-host target instead of trackingmain.
Beta β actively being built. Expect rough edges and frequent updates. Issues and feedback are welcome. The software equivalent of going to the gym for the first time.
π Live demo β lyftr-demo.fly.dev β log in with
demo@lyftr.local/password123. Shared instance, resets every hour.
Tested and working on:
- Raspberry Pi 4 (2 GB RAM, arm64 Docker image)
- Any x86 VPS β Hetzner CAX11, DigitalOcean Droplet, Oracle Free Tier
- Synology NAS via Docker (Container Manager)
- Proxmox LXC with Docker installed
- Local machine β Mac, Linux, Windows (WSL2)
Single SQLite file, minimal RAM, no external services required.
Hevy and Strong are polished apps but cloud-only, increasingly paywalled, and your data lives on someone else's server. Wger is a solid self-hosted option with a lot of features β Lyftr's focus is a more modern, mobile-first UI and a simpler deployment story. FitNotes is local-only with no sync or server deployment story.
Lyftr is for people who want a modern, mobile-first workout tracker that they fully own and can run on a $5 VPS or a Raspberry Pi in the corner. No subscription. No vendor lock-in. No "your export is a Pro feature."
| Feature | Status |
|---|---|
| Workout logging with 800+ exercise library | β |
| Program builder β reusable workout templates | β |
| Active workout mode β guided set-by-set flow | β |
| Gym Mode β full-screen card layout, one exercise at a time | β |
| Exercise detail β personal records, progression chart, muscle diagram | β |
| Dashboard β volume trends, consistency heatmap, muscle balance | β |
| Weight tracking with trend graph | β |
| lbs / kg unit support across all data | β |
| Self-hosted β all data stays on your server | β |
| Nutrition tracking β calories, macros, barcode scan, food search | β |
| PWA β installable on any device | Planned |
| Strong / Hevy CSV import | Planned |
| iOS app (Swift) | Planned |
| Field | Value |
|---|---|
demo@lyftr.local |
|
| Password | password123 |
Pre-loaded with 8 weeks of PPL workouts, 90 days of weight logs, and food logs so every page has data to explore. Shared instance β resets automatically every hour so any changes are wiped clean.
Or register your own account on the demo β your data persists until the next hourly reset, and nobody else can see it.
No clone. No build. No Go install required. Just Docker.
curl -o docker-compose.yml https://raw.githubusercontent.com/Cawlumm/lyftr/main/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/Cawlumm/lyftr/main/.env.exampleEdit .env and set a strong JWT_SECRET (32+ characters), then:
docker compose up -dOpen http://localhost in your browser and create your account. If running on a VPS, replace localhost with your server IP or domain.
All variables live in .env at the project root.
| Variable | Default | Description |
|---|---|---|
JWT_SECRET |
required | Min 32-char secret for signing tokens |
CORS_ORIGIN |
http://localhost |
Comma-separated allow-list of client origins. Use * to allow any (the API is Bearer-token based, no cookies) |
PORT |
80 |
Host port for the web interface |
BACKEND_ORIGIN |
backend:3000 |
Docker service name:port the frontend proxies /api to β not a host IP. Only change the port, to match a custom backend PORT |
Self-hosting note:
BACKEND_ORIGINis resolved over the internal Docker network, so it must use the backend's service name (backend), not your server's host or LAN IP. The default compose only exposes the backend on the Docker network β it isn't published to the host β so pointingBACKEND_ORIGINat something like192.168.1.10:3000produces a502 Bad Gateway(connect() failed (111: Connection refused)). If you set a custom backendPORT, change only the port (e.g.backend:3008).
On first startup, Lyftr automatically seeds 800+ exercises from free-exercise-db in the background. No API key. No setup required. It just works.
[startup] exercises table empty β fetching from free-exercise-db...
[startup] seed: synced 868 exercises
The seed runs async so the server is immediately available. Exercises appear in the UI within a few seconds.
Re-sync exercises: Go to Settings β Exercise Library β shows current exercise count and a progress indicator while seeding. Hit Re-sync to pull the latest exercises (safe upsert, existing workout data is untouched).
All workout data is stored in ./data/lyftr.db (SQLite). Back this up regularly. It's one file. You have no excuse.
# Backup
cp ./data/lyftr.db ./data/lyftr.db.backup
# Update to latest
docker compose pull && docker compose up -dBecause paying $15/month for a fitness app subscription is money better spent on protein powder.
sudo apt update && sudo apt install -y docker.io docker-compose-plugin
mkdir lyftr && cd lyftr
curl -o docker-compose.yml https://raw.githubusercontent.com/Cawlumm/lyftr/main/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/Cawlumm/lyftr/main/.env.example
nano .env # set JWT_SECRET and CORS_ORIGIN
docker compose up -dFor HTTPS, put Lyftr behind Caddy or nginx with a Let's Encrypt certificate.
- Workout logging + program builder
- Active workout mode (list + gym mode layouts)
- Exercise detail β PRs, progression chart, muscle diagram
- Dashboard with charts and trends
- Weight tracking with trend graph + lbs/kg support
- Docker deployment with E2E test pipeline
- Nutrition tracking β calories, macros, Open Food Facts search, barcode scan, history
- PWA β installable on any device without an app store
- Strong / Hevy CSV import β so you don't lose years of data switching
- Apple Health / Google Fit export
- iOS app (Swift)
- Hosted option (no self-hosting required)
| Layer | Technology |
|---|---|
| Backend | Go, Gin, SQLite |
| Frontend | React, TypeScript, Tailwind CSS, Vite |
| Auth | JWT with refresh tokens |
| Deployment | Docker, nginx |
# Backend (runs on :3000)
cd backend && go run main.go
# Frontend (runs on :5173, proxies /api to :3000)
cd web && npm install && npm run devSee backend/config/config.go for all supported environment variables.
Bug reports, feature requests, and pull requests are all welcome. Open an issue before submitting large changes β unlike leg day, communication should not be skipped.






