Self-hosted service
endurain-project/endurain avatar
endurain-project/endurain

Endurain: a self-hosted Strava alternative built on FastAPI, Vue and PostgreSQL

Endurain is a self-hosted fitness tracking service designed to give users full control over their data and hosting environment

2,240 stars132 forksPythonAGPL-3.0

At a glance

What is it?
A privacy focused activity tracker you run yourself, with Strava and Garmin Connect sync plus GPX, TCX and FIT import, AGPL licensing, a Codeberg home and a documented feature freeze that has not yet become an abandonment.
Who is it for?
Endurain is a credible self-hosted answer for anyone who wants their activity history on their own hardware, and the parts that make it credible are unglamorous: real Strava and Garmin Connect sync, a documented file import path, PostgreSQL with Alembic migrations, and a compose example with the environment variables already spelled out. Its rough edges are equally concrete.
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 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 8, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A Strava alternative where the data stays on your own hardware

Endurain describes itself as a self-hosted fitness tracking service built to give users full control over their data and their hosting environment. The README compares it to Strava directly and names the difference in one word: privacy, alongside customization. That positioning explains the AGPL-3.0 licensing, the emphasis on environment variable configuration, and the fact that a Docker image is published at all.

The repository has 2221 stars and 128 forks, its primary language is Python, and the last push was 2026-09-09. The star to fork ratio is telling for this kind of project: people adopt it and then run it, rather than forking and modifying it.

There is a demo instance at demo.endurain.com with the username `admin` and the password `admin`, resetting daily at midnight in the Europe/Lisbon timezone. That is worth trying before you commit to running anything, because a training platform is a UI product first and a database second. The README warns against storing anything important there, and the daily reset is the reason it works as a demo.

The stack, spelled out unusually precisely

The What Is Endurain section lists the stack in enough detail to be useful, which is not always the case. The frontend is Vue 3 with TypeScript, Tailwind CSS and shadcn-vue components, with Pinia and TanStack Query handling state. The backend is Python FastAPI with Alembic and SQLAlchemy, Apprise for notifications, `stravalib` and `python-garminconnect` for the two device integrations, and `gpxpy`, `tcxreader` and `fitdecode` for importing `.gpx`, `.tcx` and `.fit` files respectively.

PostgreSQL is the database. Jaeger provides basic tracing and monitoring, which is a small choice that says something about the project's priorities: not a metrics stack, just enough tracing to debug your own deployment.

The import libraries matter more than they look. Strava and Garmin Connect integration covers the devices people already own, but the file import path means a device that has never synced anywhere can still get its history in. For a privacy focused tracker, being able to upload a `.fit` file from a watch that talks to nobody is arguably the more important capability of the two.

The repository layout matches the split: `backend/`, `frontend/`, `docker/`, `docs/` alongside a `mkdocs.yml`, plus `aux_scripts/`, `renovate.json` for dependency updates, and the usual `CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md` and `ROADMAP.md`.

GitHub is the mirror, Codeberg is the project

The first thing the README tells you is that if you are reading it on GitHub, you are looking at a read only mirror. Issues, pull requests and all project activity are tracked on Codeberg at codeberg.org/endurain-project/endurain. The badges confirm it: the release, stars and translation badges all query the Codeberg API rather than GitHub.

That has practical consequences for anyone evaluating or contributing. A GitHub issue you file against the mirror will not reach a maintainer, so go to Codeberg. The sponsor links are a mixed bag, with GitHub Sponsors pointing at an archived repository and the current funding paths on Buy Me a Coffee, liberapay and Patreon.

The repository also carries a `.forgejo/` directory, which is the forge software behind Codeberg, and the release history mentions replacing the old Docker workflows with a single simplified one plus a new workflow that deploys the documentation automatically. The docs being built by CI rather than by hand is consistent with a project that has a `docs/` tree and a `mkdocs.yml` and expects to keep them current.

Translation runs through Codeberg Translate, and the README invites help with it, so a self-hosted project with a multi language interface is actively working on coverage rather than leaving it to drift.

A feature freeze that the README is careful about

The second note at the top of the README says Endurain is on a temporary feature freeze, and it is equally careful about what that means: the project is not paused, and the focus is shifting from new features to strengthening the foundations. A blog post explains the reasoning in more detail.

That framing is doing real work, so read it with some care. A freeze means feature requests will not be accepted in the way they were, which for a self-hosted project matters if you were planning to build something unusual on top of it. What it does not mean is that the project is winding down. The evidence points the other way: the repository was pushed on 2026-09-09, and the three most recent releases are bug fix releases rather than feature releases.

The release history shows what the maintenance has actually been spending its effort on. v0.17.5 in February 2026 fixed `.fit` uploads from a Geoid CC600, fixed SSO authentication in two separate cases, bumped dependencies and added missing translations. v0.17.6 later that month fixed mobile OAuth2 and SSO through the system browser, fixed weight being stored and displayed as a float, fixed a wrong cadence unit, fixed the activity page not updating when picking a different activity from the notification drop-down, and changed the `expires_in` logic to respond with seconds until expiry per RFC 6749 section 5.1. v0.17.7 in April 2026 was a Garmin Connect login fix and a dependency bump.

Each of those is a small correctness fix in the exact places a self-hosted user would hit a wall, which is a good sign about where the maintainer's attention is.

Deploying through the compose example and its environment file

Deployment is Docker first. The README points at `docker-compose.yml.example` in the repository as the comprehensive example, and the tree shows two more variants: `docker-compose.yml-multiple-backends.example` and `docker-compose.yml.secrets.example`, so there is a documented path for splitting backends across services and for keeping secrets out of the compose file.

The matching `.env.example` is where the required configuration lives, and its comments are more instructive than most. The database password and the PostgreSQL password must be identical, which is the kind of constraint that costs an hour if you miss it. Secrets for signing and for encryption each need real values rather than placeholders:

bash
DB_PASSWORD=changeme
POSTGRES_PASSWORD=changeme
SECRET_KEY=changeme
FERNET_KEY=changeme
TZ=Europe/Lisbon
ENDURAIN_HOST=https://endurain.example.com
BEHIND_PROXY=true
RATE_LIMIT_STORAGE_URI=redis://redis:6379/0
AUTH_SECURITY_STORAGE_URI=redis://redis:6379/0

Those two `redis://` URIs are how rate limiting and auth security storage attach to Redis in that stack, so Redis is part of the example deployment rather than an optional extra. `BEHIND_PROXY=true` tells the app to trust headers from a reverse proxy, which you want when TLS terminates somewhere else, and `ENDURAIN_HOST` is what OAuth callbacks and links are built from, so it has to match the address users actually visit.

There is also a `LOCAL_PATH` variable for data persistence volumes, documented as defaulting to `/var/opt/endurain` and intended to be FHS compliant. The file points to the documentation for the long tail of supported variables, so the ten above are the minimum rather than the full surface.

AGPL for the code, a trademark for the name

Endurain is licensed under AGPL-3.0, with a `LICENSE` file in the repository. For a network service that matters in a specific way: the AGPL asks you to offer source to users who interact with the software over a network, so if you modify it and run it as a hosted service, you owe those users the source. That is the intended trade and worth understanding before you fork it for a club or a team.

The trademark is a separate question and the README separates it carefully. Endurain is a trademark of João Vitória Silva. Self-hosting and using the name and logo is welcome for personal, educational, research and community use, all of which are non-commercial. Commercial use of the name or logos, with paid hosting, products and services named as examples, is not permitted without prior written permission. `TRADEMARK.md` holds the full details.

So a community club can run Endurain for its members under the Endurain name. A consultancy cannot put it behind a paid hosting plan and call it Endurain without asking first. That split is common in self-hosted projects and is unusually clearly stated here.

Contributions are welcome, with the README asking you to open an issue to discuss a change before submitting a pull request. With 109 open issues on record and a feature freeze in force, that request to talk first is worth honouring rather than treating as ceremony.

Editorial conclusion

Endurain is a credible self-hosted answer for anyone who wants their activity history on their own hardware, and the parts that make it credible are unglamorous: real Strava and Garmin Connect sync, a documented file import path, PostgreSQL with Alembic migrations, and a compose example with the environment variables already spelled out. Its rough edges are equally concrete. The GitHub repository is a read only mirror with development on Codeberg, there are 109 open issues, the feature freeze means gaps will not be filled on request, and the trademark policy rules out offering paid hosting under the Endurain name without written permission. The demo at demo.endurain.com, with `admin` and `admin` and a daily reset, is the fastest way to judge the interface. If you plan to run it for real, start from `docker-compose.yml.example`, set `SECRET_KEY`, `FERNET_KEY` and the two matching passwords, and read `TRADEMARK.md` before you put it anywhere public.

Frequently asked questions

What is Endurain?

A self-hosted fitness tracking service that gives users full control over their data and hosting environment. The README compares it to Strava but focuses on privacy and customization, and a Docker image is published for deployment.

Which devices and services does Endurain sync with?

Strava and Garmin Connect, through the stravalib and python-garminconnect libraries. There is also manual import of activities from .gpx, .tcx and .fit files using gpxpy, tcxreader and fitdecode.

Where does Endurain development actually happen?

On Codeberg, at codeberg.org/endurain-project/endurain. The GitHub repository is a read only mirror, so issues and pull requests opened on GitHub will not reach the maintainers.

Can I try Endurain without installing it?

Yes, there is a demo at demo.endurain.com with the username admin and the password admin. It resets daily at midnight Europe/Lisbon time, so the README warns against storing anything important there.

Can I offer Endurain as a paid hosted service?

Not under the Endurain name without prior written permission. Self-hosting and use of the name and logo are welcome for personal, educational, research and community use, but commercial use such as paid hosting, products or services needs permission.

Official sources

  1. endurain-project/endurain on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/endurain-project-endurain.svg)](https://hysenlabs.com/projects/endurain-project-endurain)