diff --git a/apps/endurain/config.json b/apps/endurain/config.json new file mode 100644 index 0000000..3847816 --- /dev/null +++ b/apps/endurain/config.json @@ -0,0 +1,93 @@ +{ + "$schema": "../app-info-schema.json", + "name": "Endurain", + "id": "endurain", + "available": true, + "short_desc": "Self-hosted fitness tracking with Strava/Garmin sync, gear tracking, multi-user", + "author": "endurain-project", + "port": 8080, + "categories": [ + "utilities", + "data" + ], + "description": "Endurain is a self-hosted fitness tracking service for athletes who want full control over their data. Features: activity import (GPX/TCX/FIT), Strava & Garmin Connect sync, gear tracking with component wear, gear defaults per activity type, multi-user with admin/user roles, follower feeds, goals, weight/steps/sleep logging, MFA TOTP, SSO (OIDC/SAML), email notifications via Apprise, multi-language, metric/imperial units, dark/light theme. Built with Vue 3 + FastAPI + PostgreSQL + Redis.", + "tipi_version": 1, + "version": "v0.17.7", + "source": "https://github.com/endurain-project/endurain", + "website": "https://docs.endurain.com", + "logo": "metadata/logo.png", + "exposable": true, + "supported_architectures": [ + "arm64", + "amd64" + ], + "created_at": 1755302400000, + "updated_at": 1755302400000, + "dynamic_config": true, + "form_fields": [ + { + "type": "password", + "label": "PostgreSQL Password", + "hint": "Password for the PostgreSQL database. Use a strong random string.", + "required": true, + "env_variable": "POSTGRES_PASSWORD", + "default": "changeme123" + }, + { + "type": "password", + "label": "Redis Password", + "hint": "Password for Redis (rate-limiting, auth storage)", + "required": true, + "env_variable": "REDIS_PASSWORD", + "default": "changeme123" + }, + { + "type": "password", + "label": "Secret Key", + "hint": "Secret key for JWT tokens and session security. Use a long random string.", + "required": true, + "env_variable": "SECRET_KEY", + "default": "changeme-secret-key-32chars-minimum" + }, + { + "type": "text", + "label": "Site URL", + "hint": "Public URL for this Endurain instance (e.g., https://endurain.yourdomain.com)", + "required": true, + "env_variable": "SITE_URL", + "default": "http://localhost:8080" + }, + { + "type": "text", + "label": "Host Port", + "hint": "External port to expose the app on", + "required": true, + "env_variable": "HOST_PORT", + "default": "8080" + }, + { + "type": "text", + "label": "Timezone", + "hint": "Timezone setting (e.g., America/New_York, Europe/Lisbon)", + "required": false, + "env_variable": "TZ", + "default": "UTC" + }, + { + "type": "boolean", + "label": "Disable Signup", + "hint": "Disable new user registration (requires admin approval)", + "required": false, + "env_variable": "DISABLE_SIGNUP", + "default": "false" + }, + { + "type": "boolean", + "label": "Require Email Verification", + "hint": "Require email verification for new accounts", + "required": false, + "env_variable": "REQUIRE_EMAIL_VERIFICATION", + "default": "true" + } + ] +} \ No newline at end of file diff --git a/apps/endurain/docker-compose.json b/apps/endurain/docker-compose.json new file mode 100644 index 0000000..484d8ff --- /dev/null +++ b/apps/endurain/docker-compose.json @@ -0,0 +1,71 @@ +{ + "$schema": "../dynamic-compose-schema.json", + "schemaVersion": 2, + "services": [ + { + "name": "endurain-postgres", + "image": "postgres:18", + "environment": [ + { "key": "POSTGRES_USER", "value": "endurain" }, + { "key": "POSTGRES_PASSWORD", "value": "${POSTGRES_PASSWORD}" }, + { "key": "POSTGRES_DB", "value": "endurain" }, + { "key": "TZ", "value": "${TZ}" } + ], + "volumes": [ + { + "hostPath": "${APP_DATA_DIR}/data/postgres", + "containerPath": "/var/lib/postgresql/data" + } + ], + "healthCheck": { + "test": "pg_isready -U endurain", + "interval": "5s", + "timeout": "5s", + "retries": 5 + } + }, + { + "name": "endurain-redis", + "image": "redis:8-alpine", + "command": ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD}"], + "volumes": [ + { + "hostPath": "${APP_DATA_DIR}/data/redis", + "containerPath": "/data" + } + ], + "healthCheck": { + "test": "redis-cli -a ${REDIS_PASSWORD} ping", + "interval": "5s", + "timeout": "5s", + "retries": 5 + } + }, + { + "name": "endurain", + "image": "codeberg.org/endurain-project/endurain:v0.17.7", + "isMain": true, + "internalPort": "8080", + "dependsOn": ["endurain-postgres", "endurain-redis"], + "environment": [ + { "key": "DATABASE_URL", "value": "postgresql://endurain:${POSTGRES_PASSWORD}@endurain-postgres:5432/endurain" }, + { "key": "REDIS_URL", "value": "redis://:${REDIS_PASSWORD}@endurain-redis:6379/0" }, + { "key": "SECRET_KEY", "value": "${SECRET_KEY}" }, + { "key": "SITE_URL", "value": "${SITE_URL}" }, + { "key": "TZ", "value": "${TZ}" }, + { "key": "DISABLE_SIGNUP", "value": "${DISABLE_SIGNUP}" }, + { "key": "REQUIRE_EMAIL_VERIFICATION", "value": "${REQUIRE_EMAIL_VERIFICATION}" } + ], + "volumes": [ + { + "hostPath": "${APP_DATA_DIR}/data/backend/data", + "containerPath": "/app/backend/data" + }, + { + "hostPath": "${APP_DATA_DIR}/data/backend/logs", + "containerPath": "/app/backend/logs" + } + ] + } + ] +} \ No newline at end of file diff --git a/apps/endurain/metadata/description.md b/apps/endurain/metadata/description.md new file mode 100644 index 0000000..8ac91a4 --- /dev/null +++ b/apps/endurain/metadata/description.md @@ -0,0 +1,60 @@ +# Endurain + +**A self-hosted fitness tracking service** + +Endurain is a self-hosted fitness tracking service designed to give users full control over their data and hosting environment. Built for amateur athletes who want to track activities, gear, and progress without vendor lock-in. + +## Features + +### 🏃 Activity Tracking +- Import GPX, TCX, FIT files (manual or bulk) +- Strava integration (sync activities & gear) +- Garmin Connect integration (sync activities, gear, body composition) +- Activity feeds and statistics (week/month) +- Privacy settings per activity + +### 🚴 Gear Management +- Track gear: wetsuits, bicycles, shoes, racquets, skis, snowboards +- Component tracking (e.g., bike chain wear, replacement schedules) +- Default gear per activity type + +### 👥 Social & Multi-user +- Admin and user profiles +- Follower system (view activities) +- User pages with stats and history + +### ⚙️ Core Features +- Multi-language support (10+ languages) +- Metric & imperial units +- Dark/light theme +- MFA (TOTP) +- SSO (OIDC/SAML) +- Email notifications via Apprise +- Goals, weight/steps/sleep logging +- Password reset via email link + +## Quick Start + +1. Install via Runtipi app store +2. Configure form fields (especially `POSTGRES_PASSWORD`, `REDIS_PASSWORD`, `SECRET_KEY`, `SITE_URL`) +3. Deploy the app +4. Access at your configured `SITE_URL` (default port 8080) +5. Default demo login: `admin` / `admin` — change immediately + +## Architecture + +Three services: +- **PostgreSQL 18** - primary database +- **Redis 8** - rate limiting, auth storage +- **Endurain** (FastAPI + Vue 3) - main app on port 8080 + +All data persists in `${APP_DATA_DIR}/data/`. + +## Links + +- **Website**: https://docs.endurain.com +- **Source**: https://github.com/endurain-project/endurain +- **Demo**: https://demo.endurain.com (resets daily) +- **Discord**: https://discord.gg/6VUjUq2uZR +- **Mastodon**: https://fosstodon.org/@endurain +- **License**: AGPL-3.0 \ No newline at end of file diff --git a/apps/endurain/metadata/logo.jpg b/apps/endurain/metadata/logo.jpg new file mode 100644 index 0000000..3385aeb Binary files /dev/null and b/apps/endurain/metadata/logo.jpg differ diff --git a/apps/endurain/metadata/logo.png b/apps/endurain/metadata/logo.png new file mode 100644 index 0000000..3385aeb Binary files /dev/null and b/apps/endurain/metadata/logo.png differ diff --git a/apps/wanderer/config.json b/apps/wanderer/config.json new file mode 100644 index 0000000..5340dce --- /dev/null +++ b/apps/wanderer/config.json @@ -0,0 +1,93 @@ +{ + "$schema": "../app-info-schema.json", + "name": "Wanderer", + "id": "wanderer", + "available": true, + "short_desc": "Self-hosted trail catalogue with GPX upload, route planning, ActivityPub federation", + "author": "open-wanderer", + "port": 3000, + "categories": [ + "utilities", + "data" + ], + "description": "Wanderer is an open-source, self-hosted trail database for organizing, planning, and sharing GPS tracks. Features: GPX/KML/FIT upload, full-text & map-based search, Valhalla routing for route planning, elevation profiles, summit logs, lists, photo galleries, waypoints, ActivityPub federation (follow explorers across instances), mobile apps for iOS/Android, plugin system (Strava, Komoot, Hammerhead integrations as WASM plugins). Built with SvelteKit + PocketBase + Meilisearch.", + "tipi_version": 1, + "version": "v0.20.0", + "source": "https://github.com/open-wanderer/wanderer", + "website": "https://wanderer.to", + "logo": "metadata/logo.png", + "exposable": true, + "supported_architectures": [ + "arm64", + "amd64" + ], + "created_at": 1755302400000, + "updated_at": 1755302400000, + "dynamic_config": true, + "form_fields": [ + { + "type": "password", + "label": "Meilisearch Master Key", + "hint": "Encryption key for Meilisearch (generate a strong random string)", + "required": true, + "env_variable": "MEILI_MASTER_KEY", + "default": "changeme-meili-master-key-32chars" + }, + { + "type": "password", + "label": "PocketBase Encryption Key", + "hint": "32-character encryption key for PocketBase database", + "required": true, + "env_variable": "POCKETBASE_ENCRYPTION_KEY", + "default": "changeme-pb-encryption-key-32chr" + }, + { + "type": "text", + "label": "Origin URL", + "hint": "Public URL for this Wanderer instance (e.g., https://wanderer.yourdomain.com)", + "required": true, + "env_variable": "ORIGIN", + "default": "http://localhost:3000" + }, + { + "type": "text", + "label": "Host Port", + "hint": "External port to expose the web UI on", + "required": true, + "env_variable": "HOST_PORT", + "default": "3000" + }, + { + "type": "boolean", + "label": "Disable Signup", + "hint": "Disable new user registration (recommended for private instances)", + "required": false, + "env_variable": "PUBLIC_DISABLE_SIGNUP", + "default": "false" + }, + { + "type": "text", + "label": "Overpass API URL", + "hint": "Overpass API endpoint for OSM data", + "required": false, + "env_variable": "OVERPASS_API_URL", + "default": "https://overpass-api.de" + }, + { + "type": "text", + "label": "Valhalla Routing URL", + "hint": "Valhalla routing engine URL (use public or self-hosted)", + "required": false, + "env_variable": "VALHALLA_URL", + "default": "https://valhalla1.openstreetmap.de" + }, + { + "type": "text", + "label": "Nominatim Geocoding URL", + "hint": "Nominatim geocoding service URL", + "required": false, + "env_variable": "NOMINATIM_URL", + "default": "https://nominatim.openstreetmap.org" + } + ] +} \ No newline at end of file diff --git a/apps/wanderer/docker-compose.json b/apps/wanderer/docker-compose.json new file mode 100644 index 0000000..3035e34 --- /dev/null +++ b/apps/wanderer/docker-compose.json @@ -0,0 +1,79 @@ +{ + "$schema": "../dynamic-compose-schema.json", + "schemaVersion": 2, + "services": [ + { + "name": "wanderer-search", + "image": "getmeili/meilisearch:v1.36.0", + "environment": [ + { "key": "MEILI_MASTER_KEY", "value": "${MEILI_MASTER_KEY}" }, + { "key": "MEILI_NO_ANALYTICS", "value": "true" } + ], + "volumes": [ + { + "hostPath": "${APP_DATA_DIR}/data/meilisearch", + "containerPath": "/meili_data" + } + ], + "healthCheck": { + "test": "curl --fail http://localhost:7700/health || exit 1", + "interval": "15s", + "timeout": "10s", + "retries": 10 + } + }, + { + "name": "wanderer-db", + "image": "flomp/wanderer-db:v0.20.0", + "dependsOn": ["wanderer-search"], + "environment": [ + { "key": "MEILI_URL", "value": "http://wanderer-search:7700" }, + { "key": "MEILI_MASTER_KEY", "value": "${MEILI_MASTER_KEY}" }, + { "key": "POCKETBASE_ENCRYPTION_KEY", "value": "${POCKETBASE_ENCRYPTION_KEY}" }, + { "key": "ORIGIN", "value": "${ORIGIN}" } + ], + "volumes": [ + { + "hostPath": "${APP_DATA_DIR}/data/pocketbase", + "containerPath": "/pb_data" + }, + { + "hostPath": "${APP_DATA_DIR}/data/plugins", + "containerPath": "/data/plugins" + } + ], + "healthCheck": { + "test": "curl --fail http://localhost:8090/health || exit 1", + "interval": "15s", + "timeout": "10s", + "retries": 10 + } + }, + { + "name": "wanderer-web", + "image": "flomp/wanderer-web:v0.20.0", + "isMain": true, + "internalPort": "3000", + "dependsOn": ["wanderer-search", "wanderer-db"], + "environment": [ + { "key": "MEILI_URL", "value": "http://wanderer-search:7700" }, + { "key": "MEILI_MASTER_KEY", "value": "${MEILI_MASTER_KEY}" }, + { "key": "ORIGIN", "value": "${ORIGIN}" }, + { "key": "BODY_SIZE_LIMIT", "value": "Infinity" }, + { "key": "PUBLIC_POCKETBASE_URL", "value": "http://wanderer-db:8090" }, + { "key": "PUBLIC_DISABLE_SIGNUP", "value": "${PUBLIC_DISABLE_SIGNUP}" }, + { "key": "UPLOAD_FOLDER", "value": "/app/uploads" }, + { "key": "OVERPASS_API_URL", "value": "${OVERPASS_API_URL}" }, + { "key": "VALHALLA_URL", "value": "${VALHALLA_URL}" }, + { "key": "NOMINATIM_URL", "value": "${NOMINATIM_URL}" }, + { "key": "PUBLIC_MAP_MAX_POLYLINES", "value": "100" } + ], + "volumes": [ + { + "hostPath": "${APP_DATA_DIR}/data/uploads", + "containerPath": "/app/uploads" + } + ] + } + ] +} \ No newline at end of file diff --git a/apps/wanderer/metadata/description.md b/apps/wanderer/metadata/description.md new file mode 100644 index 0000000..872c539 --- /dev/null +++ b/apps/wanderer/metadata/description.md @@ -0,0 +1,54 @@ +# Wanderer + +**Your trails. Your data. Your server.** + +Wanderer is an open-source, self-hosted trail catalogue for organizing, planning, and sharing GPS tracks without any paywall or subscription. + +## Features + +### 📍 Trail Management +- Upload GPX, KML, FIT and more +- Full-text and map-based search +- Route planning with Valhalla routing +- Elevation profiles and statistics +- Lists, summit logs, and tags +- Photo galleries and waypoints + +### 🌐 ActivityPub Federation +Follow explorers on other Wanderer instances — their public trails, comments, and summit logs appear in your feed. No account on their server required. Built on the same open standard as Mastodon and Pixelfed. + +### 📱 Mobile Apps +Native iOS and Android apps available. + +### 🔌 Plugin System +Integrations (Strava, Komoot, Hammerhead) run as sandboxed WASM plugins. Install plugins via `/data/plugins` volume. + +## Quick Start + +1. Install via Runtipi app store +2. Configure the form fields (especially `MEILI_MASTER_KEY`, `POCKETBASE_ENCRYPTION_KEY`, and `ORIGIN`) +3. Deploy the app +4. Access at your configured `ORIGIN` +5. Register an account (or disable signup via `PUBLIC_DISABLE_SIGNUP`) + +## Configuration + +The app uses three services: +- **Meilisearch** (search engine) - port 7700 internal +- **PocketBase** (database + auth) - port 8090 internal +- **SvelteKit Web** (frontend) - port 3000 internal (main) + +All data persists in `${APP_DATA_DIR}/data/`. + +## Plugins + +After deployment, install plugins (Strava, Komoot, Hammerhead) by downloading `.tar.gz` files from [GitHub releases](https://github.com/open-wanderer/wanderer/releases) and placing them in `${APP_DATA_DIR}/data/plugins/`, then activating in Wanderer's admin panel. + +## Links + +- **Website**: https://wanderer.to +- **Documentation**: https://wanderer.to/run/installation/quick +- **Source**: https://github.com/open-wanderer/wanderer +- **Demo**: https://demo.wanderer.to +- **Discord**: https://discord.gg/USSEBY98CP +- **License**: AGPL-3.0 \ No newline at end of file diff --git a/apps/wanderer/metadata/logo.jpg b/apps/wanderer/metadata/logo.jpg new file mode 100644 index 0000000..c8b2a76 Binary files /dev/null and b/apps/wanderer/metadata/logo.jpg differ diff --git a/apps/wanderer/metadata/logo.png b/apps/wanderer/metadata/logo.png new file mode 100644 index 0000000..c8b2a76 Binary files /dev/null and b/apps/wanderer/metadata/logo.png differ