A Spring Boot REST API for tracking fitness data: training sessions, daily habits, weight logs, and food intake. Includes optional Garmin Connect integration to sync activity and health data.
- Java 21
- Maven 3.9+
- Docker & Docker Compose (for the recommended setup)
This is the easiest way to get everything running. PostgreSQL and the app start together.
1. Clone the repo
git clone <repo-url>
cd lifestyle-tracker2. Create your .env file
cp .env.example .envOpen .env and fill in your values:
DB_NAME=fitnessdb
DB_USERNAME=fitness
DB_PASSWORD=changeme
# Only needed if you want Garmin Connect integration
GARMIN_EMAIL=[email protected]
GARMIN_PASSWORD=your-garmin-password3. Start the stack
docker compose up --buildThe app will be available at http://localhost:8080.
Static files and Java code are baked into the Docker image at build time. After any code change, rebuild and restart only the app container:
docker compose up --build app -dThen hard refresh the browser (Cmd+Shift+R on Mac, Ctrl+Shift+R on Windows/Linux). The postgres and garmin containers are unaffected.
Use this if you want to run the Spring Boot app directly with Maven.
1. Start a PostgreSQL instance
You can use Docker just for the database:
docker compose up postgresOr connect to any existing PostgreSQL instance by setting the env vars below.
2. Set environment variables
Export the variables or add them to your shell profile:
export DB_HOST=localhost
export DB_PORT=5432
export DB_NAME=fitnessdb
export DB_USERNAME=fitness
export DB_PASSWORD=changeme
# Optional — Garmin integration
export [email protected]
export GARMIN_PASSWORD=your-garmin-password3. Run the app
mvn spring-boot:runOn first startup (empty database), the app seeds a demo user with sample habits and upcoming training sessions. To reset, delete the database volume and restart:
docker compose down -v
docker compose up# Compile and package
mvn clean package
# Skip tests
mvn clean package -DskipTests
# Run tests
mvn testsrc/main/java/com/fitness/
├── config/ # DataInitializer, GlobalExceptionHandler
├── controller/ # REST controllers
├── dto/ # Request/response DTOs
├── model/ # JPA entities and enums
├── repository/ # Spring Data JPA repositories
└── service/ # Business logic
src/main/resources/
├── application.properties # App config (env-var substitution)
└── static/ # Frontend HTML pages
garmin_service.py # Python sidecar for Garmin Connect API
docker-compose.yml # Full-stack Docker setup
Dockerfile # Multi-stage build (Maven + JRE + Python)
The Garmin sidecar is a small Flask service (garmin_service.py) that proxies requests to the Garmin Connect API. It runs alongside the Spring Boot app inside Docker.
Set GARMIN_EMAIL and GARMIN_PASSWORD in your .env file to enable it. OAuth tokens are cached in a Docker volume (garmin_tokens) so you only authenticate once.
Endpoints proxied by the sidecar (accessible at port 5000 internally):
GET /garmin/activitiesGET /garmin/statsGET /garmin/sleepGET /garmin/heartrate