No description
  • Go 54.5%
  • TypeScript 36.5%
  • CSS 6.5%
  • Shell 1.9%
  • JavaScript 0.3%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-02 17:48:17 +02:00
.forgejo/workflows Give the repository the same shape as the other projects 2026-09-01 06:12:31 +02:00
assets Take the tooling that is ours out of the public repository 2026-09-01 18:12:16 +02:00
cmd/lastgym Show what the room is being used by, and stop losing half of it 2026-09-02 16:03:37 +02:00
deploy Give the repository the same shape as the other projects 2026-09-01 06:12:31 +02:00
docs Describe the photographs screen that exists 2026-09-02 12:36:54 +02:00
internal Let the space be set, and move the accounts that already exist 2026-09-02 17:44:57 +02:00
scripts Let the space be set, and move the accounts that already exist 2026-09-02 17:44:57 +02:00
web Let the space be set, and move the accounts that already exist 2026-09-02 17:44:57 +02:00
.dockerignore Give the repository the same shape as the other projects 2026-09-01 06:12:31 +02:00
.editorconfig Add project foundations 2026-08-23 18:26:28 +02:00
.env.example Give the repository the same shape as the other projects 2026-09-01 06:12:31 +02:00
.gitignore Stop tracking Python bytecode 2026-09-01 18:11:23 +02:00
bun.lock Add project foundations 2026-08-23 18:26:28 +02:00
CHANGELOG.md release: Somewhere to set the space, and everyone moved to it 2026-09-02 17:48:16 +02:00
CONTRIBUTING.md Give the repository the same shape as the other projects 2026-09-01 06:12:31 +02:00
docker-compose.yml Give the repository the same shape as the other projects 2026-09-01 06:12:31 +02:00
Dockerfile Measure what it uses, and cap it 2026-08-24 15:47:52 +02:00
go.mod Add accounts, sessions and the authorisation gate 2026-08-23 18:52:16 +02:00
go.sum Add accounts, sessions and the authorisation gate 2026-08-23 18:52:16 +02:00
install.sh update README 2026-09-01 19:14:39 +02:00
LICENSE Add project foundations 2026-08-23 18:26:28 +02:00
Makefile Add project foundations 2026-08-23 18:26:28 +02:00
NOTICE Give the repository the same shape as the other projects 2026-09-01 06:12:31 +02:00
package.json release: Somewhere to set the space, and everyone moved to it 2026-09-02 17:48:16 +02:00
README.md update README 2026-09-01 17:57:02 +02:00
SECURITY.md Let the server be updated while people are training 2026-09-01 13:19:44 +02:00
tsconfig.json Add project foundations 2026-08-23 18:26:28 +02:00


LastGYM

LastGYM

The training log that still works in a basement with no signal.

Live demo   Latest release   Apache 2.0


LastGYM





📖 Read the Documentation for detailed guides on installation, configuration, security, and everyday use.


Why LastGYM

Everyone who lifts ends up choosing between an app that keeps your training on somebody else's server and a self-hosted one that gave up on phones years ago. LastGYM was built with a simple rule: a set you recorded is never lost, and the basement with no signal is where that gets proven.

  • A whole session offline — sets, reps, weight, RPE, rest timers, recorded with no network at all and synced when there is one. Every set reaches the disk before the screen shows it.
  • A progression engine — templates, supersets, and a suggested weight for the next session instead of arithmetic in your head. It proposes; it never records what you did not confirm.
  • Progress that means something — personal records, estimated 1RM, volume by muscle and by movement pattern, plateau detection, and a load model that answers "can I push today?" before "what do I train today?".
  • Body and cardio — weight, body fat, girths and progress photos, with every derived figure showing the method behind it. Heart-rate zones from your own profile, reading .fit, .tcx and .gpx from Garmin, COROS, Polar and others.
  • Coaching without surveillance — a coach sees only the athletes who granted access, only what they granted, and revoking takes effect on the next request.
  • Notifications that arrive — a rest timer that reaches you with the screen off, through Web Push or your own ntfy, Gotify or webhook.
  • One binary, one file — no database server, no runtime, no dependencies. SQLite and the whole interface are compiled in, and a backup is a copy of one file.
  • Twenty languages, translated by hand, with right-to-left laid out properly for Arabic, Persian and Urdu.
  • Small enough for a Pi — 16 MB resident at rest with five years of training in it, measured rather than estimated.

Security & Privacy

Security

LastGYM is built from the ground up with defence-in-depth principles: argon2id with a floor configuration cannot lower, opaque sessions with CSRF checked against the session row, strict CSP headers with a per-request nonce, aggressive rate limiting, an anti-SSRF gate inside the dial for every outbound request, push payloads encrypted before they leave, and signature-verified updates.

For a detailed breakdown of our security measures, including what the threat model does not cover, see the Security Policy.

Privacy

Your training belongs to you, and the administrator is not an exception. The admin role manages accounts and the server; it has no endpoint, no view and no export that reads another person's workouts, measurements or photos. A test walks the route table on every build to keep that true.

There is no telemetry of any kind. Nothing about you or your instance is reported to us, ever.


Installation Methods

Quick Start with Docker

Images are built and published to our Forgejo registry on every release.

Using Docker Compose:

services:
  lastgym:
    image: git.codigosh.com/codigosh/lastgym:beta
    container_name: lastgym
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      - TZ=Europe/Madrid
      - LASTGYM_EXTERNAL_URL=https://gym.example.org
      # - TRUST_PROXY=true   # Uncomment if running behind a reverse proxy
    volumes:
      - lastgym-data:/data
    restart: unless-stopped

volumes:
  lastgym-data:

Using Docker CLI:

# Note: Add `-e TRUST_PROXY=true \` before the image name if running behind a reverse proxy.
docker run -d \
  --name lastgym \
  -p 127.0.0.1:8080:8080 \
  -e TZ=Europe/Madrid \
  -e LASTGYM_EXTERNAL_URL=https://gym.example.org \
  -v lastgym-data:/data \
  --restart unless-stopped \
  git.codigosh.com/codigosh/lastgym:beta

The tag is beta until there is a stable release: latest is only ever moved by a stable one, so nobody pulling it lands on a prerelease. The image is scratch and has no shell in it, and it is built without a signing key — the binary inside refuses to update itself, because updating a container is pulling a new image.

For advanced configuration options and environment variables, see the .env.example and the Configuration Guide.


Quick Install (Linux)

Run this command to install or update LastGYM automatically:

curl -fsSL https://git.codigosh.com/CodigoSH/LastGYM/raw/branch/main/install.sh | sudo sh

It asks three things — port, whether a reverse proxy sits in front, and the release channel. Answer beta: there is no stable release yet. --uninstall removes it and leaves your training where it is.

It has to be served over HTTPS. Browsers refuse to install a service worker on an insecure origin, so over plain HTTP there is no offline support — the application works perfectly right up until the moment there is no signal, which is the moment it was built for. See Installing.

The first account you create is the administrator. Open the address the installer printed and choose a username and a password; a server with somebody in it cannot be claimed again.

For more details on building from source, check the Development Guide.


Updates

LastGYM updates are delivered directly from our own Forgejo instance — no proxy, no intermediary and no telemetry.

The updater checks the signature over the checksum list before it downloads anything, then the binary's own checksum, then makes the candidate prove it runs and report its schema, then refuses any binary older than the database, takes a verified backup, and only then replaces anything. None of those has a switch. It does not need anybody to stop training first: phones record without the server and send when it is back.

For detailed updating instructions, see the Installing guide, or the Security Policy for how the signing works.


Support & Recognition

We are an open-source initiative managed through Open Collective Europe.

Financial Support

If you find our tools useful, consider supporting our infrastructure through an unconditional donation.

Acknowledgments

Special thanks to everyone supporting our mission.

Organizations

We appreciate the organizations that support us as a gesture of goodwill to help maintain our infrastructure.


Credits

  • Body diagrams:
  • Everything else drawn here: the mascot, the icons and the charts are drawn by hand in this repository — no icon library, no chart library, no frontend framework.

Full attribution, including the Go modules compiled into the binaries, lives in NOTICE.


A project by CodigoSH — built to last.