YOUR DATA. YOUR SETUP.

A gym log.
On your server.

One container serves the web app, API, and MCP endpoint. Start small with SQLite. Connect your phone when you’re ready.

1. Get the source

The repository still uses its original URL. The app inside is named SteadyGym.

git clone https://github.com/BeInLife/ezfit steadygym
cd steadygym

2. Start your instance

For a local first run, the included Compose file uses SQLite and stores data in the checkout’s data directory.

docker compose up -d --build

Open http://localhost:3000. By default, SIGNUP=first lets only the first account sign up. Create that account before allowing other people to reach the server.

3. Set the address you actually use

Set PUBLIC_URL to the server’s address. For access outside your machine, use HTTPS through a reverse proxy or a private network you manage. A phone cannot reach your computer by using localhost.

# .env, next to docker-compose.yml
PUBLIC_URL=https://gym.example.com
SIGNUP=first

After changing configuration, run docker compose up -d again. The supplied PostgreSQL configuration is in docker-compose.postgres.yml; it requires PUBLIC_URL and POSTGRES_PASSWORD.

4. Connect the native app

In the iOS app’s connection settings, enter the same reachable server address and sign in. The phone keeps its local data and synchronizes through the server. You can also use the native app locally without connecting.

5. Keep a restorable backup

For the SQLite setup, stop the app while taking a consistent copy of the data directory. Store the backup elsewhere and test restoring it. For PostgreSQL, use a database backup procedure appropriate to your deployment.

docker compose stop steadygym
# Back up ./data with your chosen backup tool.
docker compose start steadygym

Before upgrading, back up the data and read the changes. A routine export can be useful, but it is not a complete server backup.

Explore the alternatives, too.

Our draft comparisons include wger, openGym, and FitTrackee.

See self-hosted comparisons