Docs

Everything you need to get openGym running — on a phone, or on your own server. The deeper, maintainer-level docs live in the repository.

Android iPhone Self-hosting Ask an AI Import your history Backups Build it yourself FAQ

Install on Android

  1. Open the download on your phone and tap Download for Android.
  2. Your browser will ask whether it may install apps — allow it. This is standard for any app installed outside the Play Store (called sideloading), and you can revoke the permission right after.
  3. Open the downloaded openGym.apk, confirm, done. No account, no setup.
openGym is deliberately not on the Play Store — no store account between you and an open-source app. The APK is signed; updates install over the old version and keep your data.

Everything is stored on the phone itself. The only things fetched from the internet are the exercise images and animations (from a CDN, on demand).

Use on iPhone

Apple does not allow installing apps outside the App Store, so there is no iOS download — that's a platform rule, not a choice we made. What works instead:

Self-host with Docker

The self-hosted flavor adds passkey profiles, sync across devices, and (optionally) an admin dashboard. You need Docker with Compose:

git clone https://gitlab.com/DuarteSantos8/opengym
cd openGym
cp .env.example .env
docker compose pull    # prebuilt images (amd64 + arm64) — skip to build from source
docker compose up -d

Open http://localhost:8080, tap Create profile, and you're in. The first launch downloads the exercise media (~140 MB) once.

Want it reachable from your phone with passkeys? You'll need an HTTPS domain — a two-line change in .env. The full guide, including reverse-proxy examples and the invite-only/admin options, is in docs/SELF_HOSTING.md.

Settings worth knowing about

All of these live in .env; the defaults are what you get if you touch nothing.

RP_ID / ORIGINThe domain passkeys are bound to, and the full URL you serve from. The two must agree, or sign-in fails.
WEB_PORTHost port for the web UI. Default 8080.
INVITE_ONLYSet 1 and new profiles need an invite code you generate.
ALLOW_GUESTSet 0 to remove Continue without account, so everyone using the instance has a profile.
ADMIN_UIDSWhich user ids get the admin dashboard.
SESSION_DAYSHow long a sign-in lasts. Default 90.
BACKEND / PORT / NGINX_PORTFor fitting openGym into a stack that already has an api service, or putting it behind your own proxy on another port. The web container renders its nginx config at start-up, so these work on a prebuilt image.

Ask an AI about your training

openGym ships an optional MCP server: a small read-only bridge that lets a client like Claude Desktop or Cursor answer questions from your actual log — "what did I bench last week?", "which muscle have I not trained this month?", "what's my estimated 1RM on squats?"

It runs on your machine, is spawned by the client, and reads your exported data directly. Nothing is sent anywhere, and it is not part of the Docker build — if you don't use an AI assistant, it simply isn't there. Setup is a few lines of client config: mcp/README.md.

Import your training history

Coming from another tracker? Settings → Data → Import from another app reads:

Exercise names are matched against the 1,324-exercise library; anything genuinely ambiguous becomes one of your own custom exercises instead of being guessed at. A summary shows exactly what will happen before anything is written, and importing is idempotent — running it twice never duplicates a workout.

Backups

Settings → Data → Export backup (JSON) writes your entire log — plan, workouts, weights, settings — into one file. On the mobile app it goes out through the share sheet (Files, AirDrop, mail…); in the browser it downloads. Import backup restores it anywhere: another phone, your self-hosted instance, or a fresh install. That file is the whole point of openGym — your training log as a file you own.

Build it yourself

Everything on this page is built from the public repo:

FAQ

Is it really free?

Yes — free as in cost and as in freedom (AGPL-3.0). No pro tier, no locked features, no ads, and the license keeps every fork open source too.

What data does openGym collect?

None. There is no telemetry, no analytics, no crash reporting. The mobile app's only network traffic is fetching exercise media from a CDN; a self-hosted instance talks only to your own server.

Why isn't it on the Play Store / App Store?

By choice (and on iOS, by Apple's rules for sideloading). Store accounts cost money, impose terms that sit badly with the AGPL, and put a gatekeeper between you and an app whose whole point is that your data is yours.

Mobile app or self-hosted — which one should I pick?

If you just want to track your training: the mobile app. If you want your data on your own hardware, synced across devices, with profiles for the people you train with: self-host. You can start with the app and move to a server later — the backup file migrates everything.

Where does the exercise database come from?

From hasaneyldrm/exercises-dataset: 1,324 exercises with animations and instructions in 10 languages. That dataset licenses the two halves differently, and so does openGym: the exercise metadata and instruction text are MIT, while the images and animations are © Gym visual, used under the dataset's terms rather than openGym's AGPL.

openGym does not redistribute that media — your instance downloads it from the upstream source on first run. If you want to reuse it yourself, commercially or otherwise, get your own licence from Gym visual first (terms & conditions).