# 🏋️ 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](#-quick-start) - [Local Development](#-local-development) - [Docker Deployment](#-docker-deployment) - [Production Setup](#-production-setup) - [Backup Strategy](#-backup-strategy) - [Project Structure](#-project-structure) - [License](#-license) ## 🚀 Quick Start ### Prerequisites - Go 1.21+ (for local development) - Docker & Docker Compose (for containerized deployment) - Linux/macOS environment recommended ### Clone the Repository ```bash git clone https://forgejo.rozic-dev.com/Dejan/Fitnes-tracker.git cd Fitnes-tracker ``` ## 💻 Local Development ### 1. Install Go **Ubuntu/Debian:** ```bash sudo apt update sudo apt install -y golang-go go version ``` ### 2. Run the Application ```bash 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: ```bash mkdir -p fitness-data sudo chown -R 1000:1000 fitness-data sudo chmod 775 fitness-data ``` ### 2. Build and Start ```bash # 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 ```bash # 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: ```yaml 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 ```bash 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`: ```yaml 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 ```bash # 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: ```bash # 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: ```bash 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`: ```yaml ports: - "8081:8080" # Use port 8081 instead ``` ### Database Locked Ensure only one instance is running: ```bash docker compose down # Wait a few seconds docker compose up -d ``` ## 🤝 Contributing 1. Fork the repository 2. Create a feature branch: `git checkout -b feature-name` 3. Commit your changes: `git commit -m 'Add feature'` 4. Push to the branch: `git push origin feature-name` 5. Open a pull request ### Git Configuration ```bash 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](https://forgejo.rozic-dev.com/Dejan/Fitnes-tracker) - Issues: [Report a bug](https://forgejo.rozic-dev.com/Dejan/Fitnes-tracker/issues) --- **Built with ❤️ for the StrongLifts community**