TimeTracker
Quick start (60 seconds)
No git clone, no certificate warning — plain HTTP on port 8080 with bundled PostgreSQL:
curl -fsSLO https://raw.githubusercontent.com/drytrix/TimeTracker/main/docker-compose.nas.yml
echo "SECRET_KEY=$(openssl rand -hex 32)" > .env
docker compose -f docker-compose.nas.yml up -d
# open http://localhost:8080 — first login creates the admin
Latest release: v5.19.0 — see CHANGELOG.md.
First 5 minutes
- Open http://localhost:8080 and create the admin account.
- Add a client under Clients → Create Client.
- Create a project under that client (Projects → Create Project).
- Start a timer or log time against the project.
- Optional: generate a draft invoice under Invoices.
More install paths (HTTPS production, NAS UI paste, cloud): Install options.
Why TimeTracker?
- Peppol & EN 16931 e-invoicing — Send invoices yourself via the bundled Peppol Bridge; embed Factur-X / ZUGFeRD XML in PDFs. No paid SaaS middleman for e-invoicing.
- Self-hosted — Your timers, clients, and invoices stay on your server (Docker, NAS, VPS, or Raspberry Pi).
- GPL-3.0 open source — Free to use, modify, and run commercially; features are never locked behind a paywall.
- No per-user pricing — Unlimited users and projects; optional one-time supporter key only hides donate prompts.
| Feature |
TimeTracker |
Toggl Track |
Clockify |
Harvest |
| Self-hosted |
✅ Full control |
❌ Cloud only |
❌ Cloud only |
❌ Cloud only |
| Open source |
✅ GPL-3.0 |
❌ |
❌ |
❌ |
| Built-in invoicing |
✅ PDF + Peppol / Factur-X |
⚠️ Limited / paid add-ons |
⚠️ Limited |
✅ |
| Peppol / EN 16931 |
✅ Bundled bridge |
❌ |
❌ |
❌ |
| Per-seat pricing |
✅ Unlimited users |
❌ Paid seats |
⚠️ Free tier limits |
❌ Paid seats |
| Persistent server timers |
✅ |
⚠️ Client-side |
⚠️ Client-side |
⚠️ Client-side |
What is TimeTracker?
TimeTracker is a self-hosted, web-based time tracking application for freelancers, teams, and agencies who need professional time management with complete control over their data — an open-source alternative to Toggl Track, Clockify, and Harvest.
Perfect for:
- Freelancers tracking billable hours across multiple clients
- Small teams managing projects and productivity
- Agencies needing reporting and client billing
- EU businesses that must send Peppol / EN 16931 e-invoices
- Privacy-focused organizations that want self-hosted tooling
UI layout and navigation conventions: UI Guidelines.
Features
Timers, projects, clients, CRM pipeline, PDF + Peppol invoicing, expenses, reports, OIDC/SSO, REST API, and optional mobile/desktop apps — full catalog in the docs:
Screenshots
Login & profile
Projects & tasks
Kanban
Time tracking
Invoicing & clients
Reports
Admin
Create flows
Install options
| Method |
Best for |
Get started |
| One-command (above) |
Homelab, quick try |
docker-compose.nas.yml + SECRET_KEY |
| Docker image |
Servers, VPS |
docker pull ghcr.io/drytrix/timetracker:latest or Docker Hub |
| NAS compose |
QNAP, Synology, Portainer |
Paste docker-compose.nas.yml — NAS guide |
| GitHub Release |
Compose files + desktop/mobile |
Releases |
| Cloud (Render) |
Managed hosting |
 |
| Railyard |
Managed hosting |
 |
| Cloud (RepoCloud) |
Managed hosting |
 |
Full list of install paths: Distribution Guide (Portainer templates, Unraid, Railway, Fly.io, Coolify, Docker Hub)
Docker Hub namespace: images are published at drytrix/timetracker (formerly driesp/timetracker).
For a full step-by-step guide, see INSTALLATION.md.
Prerequisites
- Docker (20.10+) and Docker Compose (2.0+)
- 2GB+ RAM available for Docker containers
- Port 8080 (HTTP) or 80/443 (HTTPS production)
New to Docker? See Docker Installation Guide for your platform.
Option 1: NAS / one-file compose (recommended for first try)
Same stack as Quick start. Paste docker-compose.nas.yml into Container Station, Synology Container Manager, or Portainer; set SECRET_KEY; open http://<host>:8080.
Works on QNAP, Synology, Unraid/Portainer, and other Docker-capable NAS devices (amd64 and arm64).
Full guide: NAS Deployment Guide
Option 2: Production with HTTPS
Clone the repo and use the root compose file (nginx + self-signed cert):
git clone https://github.com/drytrix/TimeTracker.git
cd TimeTracker
cp env.example .env
# Set a strong SECRET_KEY, TZ, and CURRENCY in .env
docker compose up -d
# Access at https://localhost — accept the self-signed certificate warning
First login creates the admin account. For setup problems, see INSTALLATION.md.
Default install (no bundled AI): the main docker-compose.yml starts the app and PostgreSQL only. Optional Ollama: see AI Helper.
Complete setup guide: docs/admin/configuration/DOCKER_COMPOSE_SETUP.md · Uninstall: UNINSTALL.md
Troubleshooting: Docker Startup · CSRF · Database
Option 3: Docker with plain HTTP (development)
git clone https://github.com/drytrix/TimeTracker.git
cd TimeTracker
docker compose -f docker-compose.example.yml up -d
# Access at http://localhost:8080
Option 4: Quick test with SQLite
git clone https://github.com/drytrix/TimeTracker.git
cd TimeTracker
docker compose -f docker/docker-compose.local-test.yml up --build
# Access at http://localhost:8080
No PostgreSQL or .env required. SQLite is not recommended for production.
Need help? Getting Started Guide
💻 System Requirements
Minimum Requirements
For Small Teams (1-5 users):
- CPU: 1 core (2.0 GHz+)
- RAM: 2 GB
- Storage: 10 GB free space
- OS: Linux, macOS, or Windows (with Docker)
- Docker: 20.10+ and Docker Compose 2.0+
For Production (5+ users):
- CPU: 2+ cores (2.4 GHz+)
- RAM: 4 GB
- Storage: 20 GB free space (SSD recommended)
- OS: Linux (Ubuntu 20.04+, Debian 11+, or similar)
- Docker: 20.10+ and Docker Compose 2.0+
- PostgreSQL: 13+ (included in Docker Compose)
Recommended Requirements
For Optimal Performance:
- CPU: 4+ cores (3.0 GHz+)
- RAM: 8 GB
- Storage: 50+ GB SSD
- Network: Stable internet connection (for updates and optional telemetry)
- Backup: Automated backup solution for database
- ✅ Linux (Ubuntu, Debian, CentOS, RHEL, etc.)
- ✅ macOS (Intel and Apple Silicon)
- ✅ Windows (Windows 10/11 with WSL2 or Docker Desktop)
- ✅ Raspberry Pi (Raspberry Pi 4 with 2GB+ RAM)
- ✅ Cloud Platforms (AWS, Azure, GCP, DigitalOcean, etc.)
Database Options
Browser Support
TimeTracker works with all modern browsers:
- ✅ Chrome/Edge 90+
- ✅ Firefox 88+
- ✅ Safari 14+
- ✅ Opera 76+
📖 For detailed requirements, see Requirements Documentation
💡 Use Cases
For Freelancers
Track time across multiple client projects, generate professional invoices, and understand where your time goes. TimeTracker helps you bill accurately and identify your most profitable clients.
For Teams
Assign tasks, track team productivity, and generate reports for stakeholders. See who’s working on what, identify bottlenecks, and optimize team performance.
For Agencies
Manage multiple clients and projects simultaneously. Track billable hours, generate client invoices, and analyze project profitability — all in one place.
For Personal Projects
Even if you’re not billing anyone, understanding where your time goes is valuable. Track personal projects, hobbies, and learning activities to optimize your time.
📚 Documentation
Comprehensive documentation is available in the docs/ directory. See the Documentation Index for a complete overview.
📖 Documentation by Use Case
For New Users:
For Administrators:
For Developers:
For Troubleshooting:
🎯 Feature Documentation
Core Features:
Advanced Features:
Productivity:
Integrations & Apps:
🔧 Technical Documentation
🔒 Security & Configuration
🤝 Contributing
📋 Reference
🐳 Deployment
Local Development
# Start with HTTPS (recommended)
docker-compose up -d
# Or use plain HTTP for development
docker-compose -f docker-compose.example.yml up -d
Production Deployment
Option 1: Build from Source
# Clone the repository
git clone https://github.com/drytrix/TimeTracker.git
cd TimeTracker
# Configure your .env file
cp env.example .env
# Edit .env with production settings:
# - Set a strong SECRET_KEY: python -c "import secrets; print(secrets.token_hex(32))"
# - Configure TZ (timezone) and CURRENCY
# - Set PostgreSQL credentials (POSTGRES_PASSWORD, etc.)
# Start the application
docker-compose up -d
Option 2: Use Pre-built Images
# Use the remote compose file with published images
docker-compose -f docker/docker-compose.remote.yml up -d
⚠️ Security Note: Always set a unique SECRET_KEY in production! See CSRF Configuration for details.
AI Helper (Ollama or hosted)
TimeTracker includes an optional server-side AI helper for the web app and API clients. New installs default to AI off (AI_ENABLED=false in env.example and in the root docker-compose.yml app service) so time tracking works without downloading a large language model.
- Enable (any setup): set
AI_ENABLED=true (environment or Admin → System Settings → AI Helper).
- Ollama: set
AI_PROVIDER=ollama, AI_MODEL=..., and AI_BASE_URL to http://ollama:11434 when Ollama runs in Docker on the same Compose network, or http://127.0.0.1:11434 when Ollama runs on the host.
- Hosted OpenAI-compatible: set
AI_PROVIDER=openai_compatible and AI_API_KEY=...
The AI helper is exposed as:
- Session web UI JSON:
POST /api/ai/chat (same-origin, login required)
- REST API v1:
POST /api/v1/ai/chat (API token required, scopes read:ai/write:ai)
Time entry suggestions (when AI_ENABLED=true):
GET /api/ai/suggest — deterministic suggestions from recent patterns and active tasks; optional ?q= filters by notes/project name; ?rich=true merges LLM suggestions when configured. AI failures return deterministic results only.
- Start Timer modal: horizontal suggestion chips above the project field (refresh for LLM-enhanced suggestions).
- Log Time form: “✦ Autofill” popover and ghost-text autocomplete on the notes field (
app/static/js/ai_autocomplete.js).
All suggestion UI is hidden when AI is disabled (ai_enabled in template context).
Bundled Ollama service (Docker Compose, opt-in)
The root docker-compose.yml defines a CPU-only ollama service and a one-shot ollama-init sidecar that pulls AI_MODEL (default llama3.1, ~4.7 GB) into the ollama_data volume. These services use the Compose ai profile so they do not start by default.
Enable bundled Ollama:
-
In .env, set AI_ENABLED=true, AI_PROVIDER=ollama, AI_BASE_URL=http://ollama:11434, and your desired AI_MODEL.
-
Start the stack with the profile:
docker compose --profile ai up -d
- The app reaches Ollama at
http://ollama:11434 over the Docker network — no host ports need to be opened.
- Change the model by setting
AI_MODEL in .env (e.g. AI_MODEL=qwen2.5:3b for lighter hardware) and re-running docker compose --profile ai up -d; the init sidecar will pull the new model when needed.
- Pulled models are cached in the
ollama_data named volume, so subsequent boots are faster.
- Verify in the UI: Admin → System Settings → AI helper, then click Test connection.
- To pull additional models manually:
docker compose exec ollama ollama pull <model> (with the ai profile active).
- Hosted provider only (no Ollama containers): set
AI_PROVIDER=openai_compatible, AI_BASE_URL, and AI_API_KEY in .env; keep docker compose up -d without the ai profile.
Disable or remove AI (turn off LLM calls, stop Ollama, revoke tokens, delete ollama_data safely): UNINSTALL.md.
Encrypting stored secrets (recommended)
To store sensitive settings (OAuth secrets, mail password, AI API key, Peppol token, 2FA secret) encrypted at rest, set:
SETTINGS_ENCRYPTION_KEY (Fernet key), or
SETTINGS_ENCRYPTION_KEY_FILE (file path with the key on the first line)
Raspberry Pi Deployment
TimeTracker runs perfectly on Raspberry Pi 4 (2GB+ RAM):
# Same Docker commands work on ARM architecture
docker-compose up -d
HTTPS Configuration
Automatic HTTPS (Easiest)
# Uses self-signed certificates (generated automatically)
docker-compose up -d
# Access at https://localhost (accept browser warning)
Manual HTTPS with mkcert (No Browser Warnings)
# Use mkcert for locally-trusted certificates
docker-compose -f docker/docker-compose.https-mkcert.yml up -d
📖 See HTTPS Setup Guide for detailed instructions. HTTPS helper scripts live in scripts/ (e.g. from project root: bash scripts/setup-https-mkcert.sh, bash scripts/start-https.sh).
Monitoring & Analytics
# Alternate compose files (local-test, remote, analytics, https) are in docker/; use -f docker/docker-compose.xxx.yml
# Deploy with full monitoring stack (Prometheus, Grafana, Loki)
docker-compose -f docker-compose.yml -f docker/docker-compose.analytics.yml --profile monitoring up -d
# Grafana: http://localhost:3000
# Prometheus: http://localhost:9090
📖 See Deployment Guide for detailed instructions
📖 See Docker Compose Setup for configuration options
🔧 Configuration
TimeTracker is highly configurable through environment variables. For a comprehensive list and recommended values, see:
Common settings:
# Timezone and locale
TZ=America/New_York
CURRENCY=USD
# Timer behavior
SINGLE_ACTIVE_TIMER=true
IDLE_TIMEOUT_MINUTES=30
ROUNDING_MINUTES=1
# User management
# Note: Only the first username in ADMIN_USERNAMES is auto-created during initialization.
# Additional usernames must self-register (if ALLOW_SELF_REGISTER=true) or be created manually.
ADMIN_USERNAMES=admin,manager
ALLOW_SELF_REGISTER=false
# Security (production)
SECRET_KEY=your-secure-random-key
SESSION_COOKIE_SECURE=true
📊 Analytics & Telemetry
TimeTracker includes optional analytics and monitoring features to help improve the application and understand how it’s being used. All analytics features are:
- ✅ Disabled by default — You must explicitly opt-in
- ✅ Privacy-first — No personally identifiable information (PII) is collected
- ✅ Self-hostable — Run your own analytics infrastructure
- ✅ Transparent — All data collection is documented
What We Collect (When Enabled)
1. Structured Logs (Always On, Local Only)
- Request logs and error messages stored locally in
logs/app.jsonl
- Used for troubleshooting and debugging
- Never leaves your server
2. Prometheus Metrics (Always On, Self-Hosted)
- Request counts, latency, and performance metrics
- Exposed at
/metrics endpoint for your Prometheus server
- Stays on your infrastructure
3. Error Monitoring (Optional - Sentry)
- Captures uncaught exceptions and performance issues
- Helps identify and fix bugs quickly
- Opt-in: Set
SENTRY_DSN environment variable
4. Product Analytics (Optional - Grafana OTLP)
- Tracks feature usage and user behavior patterns with advanced features:
- Person Properties: Role, auth method, login history
- Group Analytics: Segment by version, platform, deployment
- Rich Context: Browser, device, environment on every event
- Sink config: Set
GRAFANA_OTLP_ENDPOINT and GRAFANA_OTLP_TOKEN
Rollouts and kill switches in this application are not driven by remote PostHog feature flags. Use environment variables and app/config.py (for example DEMO_MODE, ALLOW_SELF_REGISTER, ENABLE_TELEMETRY, SINGLE_ACTIVE_TIMER). Per-user UI visibility preferences are stored on the user record in the database, not in PostHog. With DEMO_MODE, the auto-created login is a standard user (no admin or settings access); see docs/deploy/RENDER.md for demo setup and upgrading old demo databases.
5. Installation Telemetry (Optional, Anonymous)
- Sends anonymous installation data via Grafana OTLP with:
- Anonymized fingerprint (SHA-256 hash, cannot be reversed)
- Application version
- Platform information
- No PII: No IP addresses, usernames, or business data
- Opt-in: Set
ENABLE_TELEMETRY=true for detailed analytics; base telemetry remains anonymous
How to Enable Analytics
# Enable Sentry error monitoring (optional)
SENTRY_DSN=https://[email protected]/project-id
SENTRY_TRACES_RATE=0.1 # 10% sampling for performance traces
# Configure Grafana Cloud OTLP sink (optional)
GRAFANA_OTLP_ENDPOINT=https://otlp-gateway-prod-eu-west-2.grafana.net/otlp/v1/logs
GRAFANA_OTLP_TOKEN=your-grafana-otlp-token
# Enable detailed analytics (optional)
ENABLE_TELEMETRY=true
TELE_SALT=your-unique-salt
APP_VERSION=1.0.0
Self-Hosting Analytics
You can self-host all analytics services for complete control:
# Use docker-compose with monitoring profile
docker-compose --profile monitoring up -d
This starts:
- Prometheus — Metrics collection and storage
- Grafana — Visualization dashboards
- Loki (optional) — Log aggregation
- Promtail (optional) — Log shipping
Privacy & Data Protection
Telemetry: TimeTracker can optionally send anonymized usage data to help improve the product (errors, feature usage, install counts). All telemetry is opt-in. No personal data is collected. To disable telemetry, set ENABLE_TELEMETRY=false or simply don’t set the environment variable (disabled by default).
What we DON’T collect:
- ❌ Email addresses or usernames
- ❌ IP addresses
- ❌ Project names or descriptions
- ❌ Time entry notes or client data
- ❌ Any personally identifiable information (PII)
Your rights:
- 📥 Access: View all collected data
- ✏️ Rectify: Correct inaccurate data
- 🗑️ Erase: Delete your data at any time
- 📤 Export: Export your data in standard formats
📖 See Privacy Policy for complete details
📖 See Analytics Documentation for configuration
📖 See Events Schema for tracked events
🛣️ Roadmap
Planned Features
- 📊 Advanced Analytics — More charts, insights, and reporting options
- 🔌 API Extensions — Additional RESTful API endpoints for integrations
- 🔔 Push Notifications — Real-time browser notifications
- 📱 Mobile & Desktop App Enhancements — Additional features for the native Flutter mobile and Electron desktop apps
- 🤖 Automation Rules — Automated workflows and task assignments
- 📈 Advanced Forecasting — AI-powered project timeline predictions
Technology stack
Flask, SQLAlchemy, PostgreSQL/SQLite, Tailwind CSS, Docker — see Architecture · Project Structure · UI Guidelines.
🤝 Contributing
We welcome contributions! Whether it’s:
- 🐛 Bug Reports — Help us identify issues
- 💡 Feature Requests — Share your ideas
- 📝 Documentation — Improve our docs
- 💻 Code Contributions — Submit pull requests
Quick Start for Contributors
-
Fork and Clone
git clone https://github.com/your-username/TimeTracker.git
cd TimeTracker
-
Set Up Development Environment
# Use SQLite for quick local testing
docker-compose -f docker/docker-compose.local-test.yml up -d
-
Make Your Changes
-
Submit a Pull Request
- Create a clear description of your changes
- Reference any related issues
- Ensure all tests pass
📖 CONTRIBUTING.md — Quick contributing overview
📖 Full Contributing Guidelines — Setup, standards, PR process
📖 DEVELOPMENT.md — Run locally, tests, releases
📖 Local Testing with SQLite — Docker SQLite setup
📄 License
TimeTracker is licensed under the GNU General Public License v3.0.
This means you can:
- ✅ Use it commercially
- ✅ Modify and adapt it
- ✅ Distribute it
- ✅ Use it privately
See LICENSE for full details
Support
If TimeTracker saves you money, a star on GitHub helps others find it.
评论