openGym: A Self-Hosted Workout Tracker You Actually Own
https://github.com/DuarteSantos8/openGym
At a glance
- What is it?
- openGym is a self-hosted gym and body-weight tracker that runs on your own server with Docker, stores all data in a folder you control, and provides passkey login, cross-device sync, guided workouts, and a library of 1,324 exercises with animated demos.
- Who is it for?
- openGym is the right choice for users who want a fully featured workout tracker without storing personal fitness data on a third-party server. The Docker deployment makes self-hosting accessible, and the feature set covers most strength training workflows including progression rules, 1RM estimation, and plan sharing.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 58 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Who openGym Is For
Most commercial workout apps store your training history on their servers, require an account, and may disappear if the company shuts down. For users who want control over their fitness data, those trade-offs are unacceptable.
openGym is built for that audience. It is a self-hosted web application that runs on a server or a home machine and keeps all data in a folder you own. There is no central account, no subscription, and the README explicitly states no telemetry. The application is installable as a home-screen app on a phone, works offline, and syncs across devices when all devices connect to the same self-hosted instance.
The target user is technically comfortable enough to run Docker on a machine they control, but does not want to write their own tracking system. The feature set goes well beyond a simple log: 1,324 exercises with animated demos, guided workouts with a rest timer, body weight tracking, and several automated progression systems make it a complete training environment for strength training and body-weight work.
Architecture: React Frontend, Node API, and nginx
openGym splits into three Docker services defined in docker-compose.yml.
The media service runs once at startup to download approximately 140MB of exercise images and GIFs from the hasaneyldrm/exercises-dataset repository (CC licensed). Once downloaded, the files are cached in the ./media directory and the service does not run again on subsequent starts.
The api service runs a Node.js backend with no framework, listening on PORT 3000. It handles passkey authentication, per-user data storage, and session management. All data is written to DATA_DIR=/data, which is mounted from the ./data directory on the host. The README specifically says to back this directory up; it contains users, passkeys, per-user state, and the session secret.
The web service builds the React frontend (using Vite) in a multi-stage Docker build and serves the resulting static files through nginx on port 8080 by default (configurable via WEB_PORT). The nginx configuration also proxies /api to the api service and serves the exercise media from the shared volume. Both the web and api Docker images are available as prebuilt images from ghcr.io/duartesantos8, so most users do not need to build from source.
Passkey authentication (Face ID, Touch ID, fingerprint) means there are no passwords. Each profile keeps its own data. The admin dashboard, which shows per-user history and allows account management, is off by default and must be explicitly enabled.
Quick Start with Docker Compose
You need Docker with Compose installed. Clone the repository and copy the environment file:
git clone https://github.com/DuarteSantos8/openGym
cd openGym
cp .env.example .envEdit the .env file with your configuration (the WEB_PORT defaults to 8080 if not set), then bring the stack up:
docker compose upThe first run downloads the exercise media, which is approximately 140MB. Subsequent starts skip this step if the media is already present. The application is then available at http://localhost:8080 (or whatever WEB_PORT you set).
A live browser demo is available at https://duartesantos8.github.io/openGym that runs entirely client-side on example data. Passkey sign-in, cross-device sync, and the admin dashboard are not available in the demo because there is no server behind it. Those features only exist in a self-hosted instance.
A standalone Android APK is also available for download that stores data on the phone with no server required, though it lacks the cross-device sync and admin dashboard.
Workout Tracking Features and Progression Rules
The guided workout flow is the core daily interaction. The application knows what day it is and starts the current day's scheduled session. It asks for body weight first, pre-fills exercise weights from the last session, and provides a rest timer. When a personal record is matched or broken, it detects and records it.
Progression is configured per routine or overridden per exercise. Four rules are available: linear progression, Greyskull LP (which uses an AMRAP top set, doubles weight jumps, and triggers 10% resets on missed reps), double progression through a rep range, and adding time for timed exercises. The application calculates target weights automatically before a session opens and shows which progression rule produced each target.
Estimated 1RM is calculated per exercise from the best eligible set, with a progress curve and a calculator for hypothetical sets. The calculation will not extrapolate above 12 reps, which is an explicit design constraint.
Timed exercises (planks, hangs, wall sits) are logged by time rather than reps, with a work timer that counts the set itself separately from the rest timer. Supersets are supported: exercises marked as a pair log back-to-back with a rest only after the pair completes. Cardio logs time and speed rather than weight and reps.
Import, Export, and Multi-Language Support
openGym can import workout history from FitNotes (Android and iOS), Strong, and Hevy. Body weight can be imported from an Apple Health export. On import, exercise names are matched against the built-in library; anything unrecognised becomes a custom exercise so that no history is lost.
Export is a one-tap JSON dump covering all workout history and body weight data. This is the migration path out of openGym if needed.
The plan sharing feature exports a routine schedule as a small file (no workouts or weigh-ins included) that another user can import. Import merges the incoming plan with the existing schedule without overwriting the recipient's data. Plans can also be printed as a PDF.
The interface is translated into 12 languages: EN, DE, ES, FR, IT, PT, PL, TR, RU, ZH, KO, and HI. Exercise instructions are localized in 10 of those languages and loaded on demand to avoid increasing the initial load.
Limitations and When openGym Is Not the Right Tool
The self-hosted requirement is the primary limitation. Running a server, maintaining Docker, and backing up the ./data volume is work that commercial apps handle for you. If you lose the server without a backup, all workout history is gone.
The application has no external API documented in the README. Third-party integrations, automated imports from wearables, or exporting data to BI tools would require either the JSON export or direct access to the data directory.
The admin dashboard is limited to basic user management: who is training, per-user history, disabling accounts, and invite-only signup. It does not provide aggregate analytics across users or bulk data export tools.
The AGPL-3.0 license is a meaningful constraint for developers: if you modify and distribute the software (even as a hosted service), you must release the source code of your modifications under the same license. Teams building proprietary fitness platforms should treat this as a hard constraint.
Maintenance Status and License
openGym is licensed under AGPL-3.0. The last push to the main branch was on 2026-08-03. The repository includes a CHANGELOG.md, CONTRIBUTING.md, and SECURITY.md.
The project is a fork or mirror at arvids-unavailable/openGym; the actual upstream repository with the active deployment is DuarteSantos8/openGym, and the Docker images are published from that repository at ghcr.io/duartesantos8. The README links to the upstream repository for the clone URL.
A live hosted instance at opengym.duarte-santos.ch exists for testing and reference. The repository contains a render.yaml file, which indicates the project has been deployed on Render, a cloud platform, likely for the demo or reference instance.
Editorial conclusion
openGym is the right choice for users who want a fully featured workout tracker without storing personal fitness data on a third-party server. The Docker deployment makes self-hosting accessible, and the feature set covers most strength training workflows including progression rules, 1RM estimation, and plan sharing. It is the wrong choice for users who need professional coaching integrations, API access for third-party apps, or a fully managed service with no server to maintain. The AGPL-3.0 license means that if you modify and distribute the software, you must release those modifications under the same license. Before deploying, back up the ./data volume, which stores all user data, passkeys, and session secrets.
Frequently asked questions
How does openGym handle data if the server goes down?
All user data is stored in the ./data directory on the host machine, which is mounted as a volume into the api Docker container. If the server is unavailable, the app works offline using data cached in the browser. Recovery requires restoring from a backup of the ./data directory. The README specifically recommends backing it up.
Does openGym support multiple users on the same instance?
Yes. Each user creates their own profile with passkey authentication, and each profile keeps its own data. An optional admin dashboard lets the instance owner see who is training, view per-user history, disable accounts, and enable invite-only signup. The admin dashboard is off by default.
Can openGym import workout history from other apps?
The README documents import support for FitNotes (Android and iOS), Strong, and Hevy. Body weight can be imported from an Apple Health export. Exercise names are matched against the built-in library; unrecognised names become custom exercises so no history is dropped.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/arvids-unavailable-opengym)