openGym is an open-source, self-hosted fitness and body-weight tracker designed for people who want complete control over their workout data. Instead of storing training history on a third-party service, it runs on your own server and keeps your data in files you control.
The application combines workout planning, guided training, body-weight tracking, statistics, muscle analysis, and cross-device synchronization in a web application that can also be installed as a Progressive Web App.
Features
openGym provides a weekly workout planner with routines organized by day. Users can create and modify training sessions, move workouts between days, and choose from predefined workout plans such as Push/Pull/Legs, Upper/Lower, Full Body, and 5×5.
The exercise library contains more than 1,300 exercises with animated demonstrations. Exercises can be searched, browsed by muscle group, and filtered according to available equipment.
During workouts, the application supports regular sets, supersets, warm-ups, cardio, rest timers, and exercise tracking. It records training history and provides statistics including personal records and progress charts.
Muscle analysis is another notable feature. openGym can show which muscles are being trained, fatigued, or detrained, helping users understand how their training volume is distributed over time.
The application can import workout history from services and applications including FitNotes, Strong, and Hevy. This makes switching to a self-hosted system considerably easier for existing users.
Authentication uses passkeys, while the application can operate offline and synchronize data when connectivity returns. The synchronization system uses revisions to prevent one device from silently overwriting changes made by another device.
Download openGym APK v1.3.9 - Software Mirrors |
|---|
openGym APK v1.3.9 for Android |
openGym APK v1.3.9 Source Code |
openGym APK v1.3.9 Release Notes:The milestone was "edit your history", and it is in: fix a saved workout after the fact, move it to another day, change how long it took, attach photos and videos to it. Around it, the two reports from Discord that mattered most — a paired phone that quietly stopped syncing and lost a week, and a routine planned at 2 × 10 that opened at 2 × 15 — are fixed at the root. Password sign-in for instances that want it, more than one passkey per profile, your own picture on your own exercises, Structural Balance, plate loading per set, the rest countdown in an Android notification, Ukrainian and Arabic. Thirty-nine community pull requests from eighteen contributors, plus five more taken in part. Web bundle, APK and API image. The two reports from Discord
server refused a phone's sign-in once — "Sign out everywhere" does that, so does an expired token — the next start of the app unpaired it silently but kept you on screen, every sync after that went nowhere and was counted as done, and Disconnect then wiped the phone. Every paired phone since v1.2.10 could get there. Now:
-- cannot be reached, a server that refuses this phone, an answer that is not the server's, and -- phone-only or guest use.
-- in that state from an earlier version are healed when they start, and their unsynced workouts -- reach the server once they are paired again.
-- still waiting, and a Sync now button.
-- export it, or go ahead anyway. Going ahead keeps a copy on the device, and it is merged back -- the next time you connect to the same account.
-- with the server's. A phone in use renews its sign-in on its own.
-- anything, and a kg ↔ lb conversion, a reset or a backup import now reaches every device.
--
the last time you did that exercise in any routine, so a 2 × 10 day opened at the 2 × 15 you had done somewhere else. Now a planned session starts from the plan (Settings → "Planned sessions start from": your plan, or your last session), progression runs per routine slot and falls back to the exercise's history only when the slot has none, an edited plan restarts progression with its new weight, and the card says "Plan: 2 × 10" (or "2 × 10–15" for a range).
#297) before it adds weight.
tracks the revision it last saw, and a conflict keeps the latest edit of every routine and workout instead of whole copies.
slow connection no longer cuts a download off halfway. Editing your history
in the same screen you logged it on; progression and records re-read the corrected session. A workout emptied in the editor offers to delete it instead of saving nothing.
touching what you lifted.
detail. They live on your server and the device, never in the synced data.
rows only look at the history from before that day.
workout copies as text, a finished session saves as a routine of its own (Space-Hermes, #211), and every weigh-in has a history with weekly averages.
an injury day stays out of the next session's numbers. Accounts and sign-in
profile's passkeys to add, rename or remove, and Add another device shows a one-time code and QR; the code creates a passkey on the new device, never a session by itself. During a workout
Skip, on time with the screen off. A louder chime, and a Vibrate switch of its own.
the plates you own; "No bar" Smith machines count from zero, and drop sets land on a weight you can actually load.
exercise, for a keyboard or a Bluetooth button.
(Space-Hermes, #204). The rest timer and a hold can no longer run at once (kurktchiev, #251).
next workout card peeks in while you swipe (Space-Hermes, #202, sgoendoer, #113); "Set current" goes straight to card view (bluzername, #262, xwr3, #260); typing an exact RIR/RPE no longer ticks the set on the first keystroke (kurktchiev, #288). Plan, library and stats
Poliquin, Thibaudeau and ATG ratios and names the weakest one.
Vaibhav159's #246) — one photo, GIF or short video (up to 40 MB and 60 s) and one link per custom exercise. The file is stripped of its location data, kept on your server and on the device, never in the synced data, and works offline once seen; a YouTube link makes no request until you tap it. Shared plans carry the link, never the file.
and rule; print a single routine or save it as PDF (Teo230, #282); swipe left to delete a routine in Plan (Agripa22, #286); a drag handle on computers (seals187, #277, sgoendoer, #114).
exercise search (GitLab !31), "benchpress" finds "bench press", cardio speed in mph for imperial users, the activity heatmap by time or by volume (Space-Hermes, #205), repeated exercises add up the same way in History and Stats (Space-Hermes, #212), a changed load cascades down the sets without overwriting the ones you set by hand (Space-Hermes, #209), and the Home body-weight card can be hidden (sacgsxr, #279). Languages
!36) — seventeen languages in all.
Russian (dima-po, #266), Italian and French (giulioleuci, #254), next to Brazilian Portuguese and Hungarian — each with a switch to show the English name beside it, or only the English name.
of profiles that never chose one; otherwise a new visitor starts in their browser's language.
imports that read localized month names (sTOrM2202, #273).
from while you were signed out. The AI Coach
its proposal, instead of failing as "unusable" (fama-lama, #313).
#311).
the demo Coach's failure state and the intake line are fixed (kurktchiev, #289); a weekly review is due until it has run, not for one minute a week (kurktchiev, #249).
(thedandano, part of #187), and the phone refuses a plain
Imports
holds come in as seconds. Hevy: supersets come in as supersets. The import summary shows the year when the range is not this year. Android and iPhone
and with three-button navigation the tab bar sits above the navigation bar, so a tap on a tab no longer lands on Home or Recents.
upload. The iOS build targets iOS 15.5 (clown-doing-code, #270).
backups go to
Self-hosting
admin's "last sync" counts pulls as well as pushes. Security and robustness
log, every id, and the "compare with others" figures — is bounded field by field before it is sent, so no text from another account can reach your prompt and an oversized request is never made.
(kurktchiev, #249); a push that carries nothing of the profile can no longer empty it on the server; the admin's activity log names what each pause was for. Community pull requests
by time or volume (#205), load cascades that keep manual edits (#209), save a session as a routine (#211), consistent totals for repeated exercises (#212), the swipe preview (#202).
the part of #250 this release took, the timer and hold fixes (#251), the API reference with the Coach routes (#255), check-locales that reads the translations (#256), sheet pinning (#257), a lighter tab bar (#258), and three Coach and effort fixes (#287, #288, #289).
(#297), the service-worker timeout (#298).
(#245), giulioleuci (#254), mkoester (#290), illinoiseeee (#285), clown-doing-code (#270), sTOrM2202 (#273), sacgsxr (#279), Agripa22 (#286); on GitLab smsmy (!36) and Josevi (!140).
Vaibhav159 (#246). Thank you to everyone who reported, tested and wrote code for this one: andi242, seals187, Supportlik, Diego-Sanchez2000, danielkleinert, tpodolak, svillar, expressiveminute, ncbachh, codedmind, Teo230, Flxp49, xwr3, sgoendoer, fama-lama, SSamDav, edgardjnr, ItzEarthy, asierlama, Space-Hermes, kurktchiev, bluzername, dima-po, Parth-Vasave, vitox013, chriscowley, ameer-khan-ashraf, AlexRomero12, giulioleuci, mkoester, illinoiseeee, clown-doing-code, sTOrM2202, sacgsxr, Agripa22, smsmy, Josevi, AlexanderVott, thedandano, horusglez and Vaibhav159. Upgrading
a phone still on v1.3.8 can still get stuck.
-- at least 256 MB of memory when it is on.
-- bundled
--
Known and not fixed: counts in Russian, Ukrainian and Polish still use the English two-form plural rule ("2 дней" where it should read "2 дня"). The Ukrainian, Arabic, Hindi, Korean, Thai and Chinese packs have not been read by a native speaker yet — corrections are very welcome.
Both images are linux/amd64 + linux/arm64. Android: Published on GitHub on 2026-09-28, mirroring the GitLab release of the same tag, where the artefacts above were built. The same images are on GHCR, built from this release by GitHub Actions: |
Performance and Compatibility
openGym is designed primarily as a self-hosted web application, but it also provides an Android application and can be installed as a PWA. The Docker deployment supports both AMD64 and ARM64, making it suitable for conventional servers as well as ARM-based systems.
The deployment architecture is relatively lightweight. The API uses Node.js, while the frontend is served through nginx. User data is stored under the application's data directory, including profiles, workout state, settings, and the session signing key. This makes backups straightforward because backing up the data directory effectively backs up the application data.
Offline functionality is particularly useful for a fitness tracker because workouts can continue even when the phone temporarily loses connectivity. Changes that have not reached the server are retained, and the application indicates when it is operating offline.
There are some important self-hosting considerations. Passkey authentication requires a properly configured HTTPS origin when accessing the application from a phone. The project provides guides for Cloudflare Tunnel, Caddy, Traefik, nginx, LAN HTTPS, and Kubernetes deployments.
The exercise media also deserves attention. The application downloads the exercise images and animations from an upstream dataset rather than redistributing them directly. The repository explicitly notes that the media has separate third-party licensing considerations and should not automatically be treated as covered by openGym's AGPL license.
System Requirements
Docker with Docker Compose for the recommended self-hosted deployment
AMD64 or ARM64 system for the provided container images
Persistent storage for application data and exercise media
HTTPS and a suitable domain when using passkeys from external devices
Android device for the native Android application
Modern web browser for the web/PWA interface
Pros and Cons
Pros
Open-source and self-hosted
Your workout data stays under your control
No subscription
No advertising
No required third-party account
Passkey authentication
Offline workout support
Cross-device synchronization
Progressive Web App support
Android application
Extensive exercise library
Animated exercise demonstrations
Workout planning and guided sessions
Supersets, warm-ups, and cardio tracking
Body-weight tracking
Muscle fatigue and detraining analysis
Personal records and statistics
Imports from FitNotes, Strong, and Hevy
Docker deployment
AMD64 and ARM64 container images
Kubernetes deployment support
Cons
Self-hosting requires some technical knowledge
HTTPS configuration is necessary for convenient passkey access from phones
Users are responsible for server backups and maintenance
Exercise media has separate third-party licensing considerations
The project is relatively young compared with established commercial fitness platforms
Some advanced functionality is still actively evolving
How to Install
The simplest deployment method is Docker Compose.
Clone the repository, create the environment file, pull the prebuilt images, and start the services:
git clone https://github.com/DuarteSantos8/openGym
cd openGym
cp .env.example .env
docker compose pull
docker compose up -dThe application can then be accessed through the configured web port. The first startup downloads the exercise media required by the application.
For access from a phone, configure HTTPS and a domain before relying on passkey authentication. The project documentation provides deployment examples for common reverse proxies and tunnel solutions.
Once installed, create a profile and configure your weekly routine. Existing workout history can also be imported from supported fitness applications.
Final Verdict
openGym is an impressive self-hosted alternative to conventional workout tracking services. Its strongest feature is not simply workout logging, but the combination of data ownership, offline support, passkey authentication, cross-device synchronization, exercise analytics, and a surprisingly complete training workflow.
The Docker-based deployment is particularly attractive for technically inclined users. The application can run on relatively inexpensive hardware, while its data directory makes backup and migration straightforward.
The main drawback is that self-hosting transfers responsibility for availability, HTTPS, backups, and updates to the user. The separate licensing situation surrounding exercise media is another consideration for anyone redistributing an installation.
For users who want a modern fitness tracker without handing their workout history to a third-party service, openGym is an excellent project and one of the more compelling self-hosted fitness applications available.




