6.5 KiB
🏋️ Fitness Tracker
A lightweight, self-hosted fitness tracking application designed for StrongLifts 5×5 powerlifting programs. Built with Go and SQLite for simplicity, privacy, and performance.
✨ Features
- Workout Logging: Track exercises with start and finish times
- A/B Templates: StrongLifts-style alternating workout plans
- Automatic Rest Tracking: Monitor recovery time between sets
- Volume Analytics: Daily, weekly, and monthly training volume statistics
- Self-Hosted: Complete data ownership with SQLite backend
- Docker Support: Containerized deployment with proper UID/GID handling
- Persistent Storage: External database mounting for easy backups
📋 Table of Contents
- Quick Start
- Local Development
- Docker Deployment
- Production Setup
- Backup Strategy
- Project Structure
- License
🚀 Quick Start
Prerequisites
- Go 1.21+ (for local development)
- Docker & Docker Compose (for containerized deployment)
- Linux/macOS environment recommended
Clone the Repository
git clone https://forgejo.rozic-dev.com/Dejan/Fitnes-tracker.git
cd Fitnes-tracker
💻 Local Development
1. Install Go
Ubuntu/Debian:
sudo apt update
sudo apt install -y golang-go
go version
2. Run the Application
DATABASE_URL=./fitness.db go run main.go
The application will be available at http://localhost:8080
The SQLite database will be created as ./fitness.db in the project directory.
🐳 Docker Deployment
1. Prepare the Environment
Create the data directory with proper permissions:
mkdir -p fitness-data
sudo chown -R 1000:1000 fitness-data
sudo chmod 775 fitness-data
2. Build and Start
# Build the Docker image
docker compose build
# Start the application
docker compose up -d
# View logs
docker compose logs -f
3. Verify Installation
The application should now be running at http://localhost:8080
Check the logs for confirmation:
Using database file: /data/fitness.db
Listening on :8080 ...
4. Managing the Container
# Stop the application
docker compose down
# Restart the application
docker compose restart
# Rebuild after code changes
docker compose build
docker compose up -d
🔧 Docker Configuration
The docker-compose.yml configuration:
services:
fitness:
build: .
container_name: fitness-tracker
restart: unless-stopped
environment:
- DATABASE_URL=/data/fitness.db
volumes:
- ./fitness-data:/data
ports:
- "8080:8080"
Key Features:
- Volume Mount:
./fitness-data→/data(persistent storage on host) - Database Location:
fitness-data/fitness.db - Auto-restart: Container restarts automatically unless manually stopped
- Non-root User: Runs as UID 1000 for security
Verify Container User
docker exec -it fitness-tracker id
Expected output:
uid=1000(appuser) gid=1000(appuser)
🌐 Production Setup
Reverse Proxy with Traefik
Add these labels to your docker-compose.yml:
services:
fitness:
# ... existing configuration ...
labels:
- "traefik.enable=true"
# Public domain
- "traefik.http.routers.fitness.rule=Host(`fitness.domain.com`)"
# Listen on HTTP & HTTPS
- "traefik.http.routers.fitness.entrypoints=web,websecure"
# Force HTTPS using your GLOBAL redirect middleware
- "traefik.http.routers.fitness.middlewares=redirect-to-https, fitness-auth"
# TLS + Let's Encrypt
- "traefik.http.routers.fitness.tls=true"
- "traefik.http.routers.fitness.tls.certresolver=letsencrypt"
# App internal port
- "traefik.http.services.fitness.loadbalancer.server.port=8080"
# - "traefik.http.routers.traefik.middlewares=fitness-auth"
#- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$8EVjn/nj$$GiLUZqcbueTFeD23SuB6x0" # admin:admin123
#- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$apr1$yGKxPD8U$z4eeZaKNzoASEpr2yh4wQ" # admin:admin123
- "traefik.http.middlewares.fitness-auth.basicauth.users=Dejan:$$apr1$$F5Y8CeQ1$$C2jX95nwyeJAjhtGxvnOJ/" # admin:admin123
networks:
- traefik_default
networks:
traefik_default:
external: true
💾 Backup Strategy
Manual Backup
# Copy data directory
cp -r fitness-data fitness-data-backup-$(date +%Y%m%d)
# Create compressed archive
tar -czvf fitness-backup-$(date +%Y%m%d).tar.gz fitness-data/
Automated Backup Script
Create a cron job to back up daily:
# Edit crontab
crontab -e
# Add daily backup at 2 AM
0 2 * * * tar -czvf ~/backups/fitness-$(date +\%Y\%m\%d).tar.gz ~/Fitnes-tracker/fitness-data/
📁 Project Structure
Fitnes-tracker/
├── main.go # Application entry point
├── go.mod # Go module dependencies
├── go.sum # Dependency checksums
├── Dockerfile # Container build instructions
├── docker-compose.yml # Docker Compose configuration
├── readme.md # This file
├── .gitignore # Git ignore rules
└── fitness-data/ # Persistent data directory (not in git)
└── fitness.db # SQLite database
🛠️ Troubleshooting
Permission Issues
If you encounter database permission errors:
sudo chown -R 1000:1000 fitness-data
sudo chmod 775 fitness-data
docker compose restart
Port Already in Use
Change the port mapping in docker-compose.yml:
ports:
- "8081:8080" # Use port 8081 instead
Database Locked
Ensure only one instance is running:
docker compose down
# Wait a few seconds
docker compose up -d
🤝 Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Commit your changes:
git commit -m 'Add feature' - Push to the branch:
git push origin feature-name - Open a pull request
Git Configuration
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
📝 License
This project is private and proprietary.
🔗 Links
- Repository: https://forgejo.rozic-dev.com/Dejan/Fitnes-tracker
- Issues: Report a bug
Built with ❤️ for the StrongLifts community