Self-Host TimeTagger with Docker Compose

What Is TimeTagger?

TimeTagger is a lightweight, open-source time tracking tool that uses tags instead of rigid project structures. Its interactive timeline view lets you drag and drop time entries, set daily or weekly targets, and export reports as PDF or CSV. It runs on Python with an embedded SQLite database — no external database needed. It replaces Toggl ($10-20/user/month), Clockify, and Harvest.

Updated February 2026: Verified with latest Docker images and configurations.

Official site: timetagger.app | GitHub

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 256 MB of free RAM
  • A domain name (recommended for HTTPS — passwords are sent in plaintext over HTTP)

Docker Compose Configuration

Create a docker-compose.yml file:

services:
  timetagger:
    image: ghcr.io/almarklein/timetagger:v26.1.3
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - timetagger_data:/root/_timetagger
    environment:
      # Bind to all interfaces on port 80 inside the container
      TIMETAGGER_BIND: "0.0.0.0:80"
      # Data directory inside the container
      TIMETAGGER_DATADIR: "/root/_timetagger"
      # Log level: debug, info, warning, error
      TIMETAGGER_LOG_LEVEL: "info"
      # User credentials — CHANGE THIS
      # Format: username:bcrypt_hash
      # Generate hashes at https://timetagger.app/cred
      TIMETAGGER_CREDENTIALS: "${TT_CREDENTIALS}"

volumes:
  timetagger_data:

Create a .env file alongside your docker-compose.yml:

# Generate your credential hash at https://timetagger.app/cred
# Format: username:bcrypt_hash
# Example (user: admin, password: changeme):
TT_CREDENTIALS=admin:$$2a$$08$$0CD1NFiIbancwWsu3se1v.RNR/b7YeZd71yg3cZ/3whGlyU6Iny5i

Important: In .env files, $ signs in bcrypt hashes must be escaped as $$.

Start the stack:

docker compose up -d

Initial Setup

  1. Open http://your-server-ip:8080 in your browser
  2. Log in with the username and password you configured in the credentials
  3. You’ll see the interactive timeline — start tracking time by clicking the start button or dragging on the timeline
  4. Add tags to your time entries by typing #tagname in the description

For production deployments, use the non-root image variant:

services:
  timetagger:
    image: ghcr.io/almarklein/timetagger:v26.1.3-nonroot
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - timetagger_data:/opt/_timetagger
    environment:
      TIMETAGGER_BIND: "0.0.0.0:80"
      TIMETAGGER_DATADIR: "/opt/_timetagger"
      TIMETAGGER_LOG_LEVEL: "info"
      TIMETAGGER_CREDENTIALS: "${TT_CREDENTIALS}"

volumes:
  timetagger_data:

Note the volume path changes from /root/_timetagger to /opt/_timetagger for the non-root variant.

Configuration

Adding Multiple Users

Separate multiple user credentials with commas:

TT_CREDENTIALS=alice:$$2a$$08$$hash1here,bob:$$2a$$08$$hash2here

Each user gets their own isolated time tracking data.

Key Settings

Environment VariableDefaultPurpose
TIMETAGGER_BIND127.0.0.1:8080Server address and port
TIMETAGGER_DATADIR~/_timetaggerSQLite database location
TIMETAGGER_LOG_LEVELinfoLogging verbosity
TIMETAGGER_CREDENTIALS(none)User authentication
TIMETAGGER_PATH_PREFIX/timetagger/URL path prefix
TIMETAGGER_APP_REDIRECTfalseRedirect root to app

Proxy Authentication

If you use Authelia, Authentik, or another SSO proxy, TimeTagger supports proxy auth:

environment:
  TIMETAGGER_PROXY_AUTH_ENABLED: "true"
  TIMETAGGER_PROXY_AUTH_TRUSTED: "172.16.0.0/12"
  TIMETAGGER_PROXY_AUTH_HEADER: "X-Remote-User"

This trusts the X-Remote-User header from your authentication proxy for automatic login.

Reverse Proxy

TimeTagger sends passwords in plaintext over HTTP — HTTPS via a reverse proxy is strongly recommended for production.

Example Nginx Proxy Manager configuration:

FieldValue
Domaintime.yourdomain.com
Schemehttp
Forward Hostnameyour-server-ip
Forward Port8080
SSLRequest a new certificate

For more details: Reverse Proxy Setup

Backup

TimeTagger stores everything in a single SQLite database file inside the data volume.

docker run --rm -v timetagger_data:/data -v $(pwd):/backup alpine \
  cp /data/timetagger.db /backup/timetagger-backup-$(date +%Y%m%d).db

For a comprehensive approach: Backup Strategy

Troubleshooting

Login Not Working

Symptom: Credentials rejected at login page Fix: Verify your bcrypt hash. Generate a fresh one at timetagger.app/cred. In Docker Compose YAML, escape $ as $$. In .env files, also use $$ escaping. Test by printing the variable:

docker compose exec timetagger printenv TIMETAGGER_CREDENTIALS

Timeline Not Loading

Symptom: Page loads but timeline is blank or shows errors Fix: Check browser console for JavaScript errors. TimeTagger requires a modern browser with WebSocket support. Try clearing browser cache or using incognito mode. Verify the container is healthy:

docker compose logs timetagger

Data Not Persisting After Restart

Symptom: Time entries disappear after docker compose down && docker compose up Fix: Ensure you’re using a named volume (not a bind mount typo). Check that TIMETAGGER_DATADIR matches the volume mount path. For the default image, data is at /root/_timetagger; for non-root, it’s at /opt/_timetagger.

Resource Requirements

ResourceUsage
RAM50-100 MB idle, 150 MB under load
CPUMinimal — single-core adequate
Disk~50 MB for application, <10 MB per active user

TimeTagger is one of the lightest time tracking tools available. It can run comfortably on a Raspberry Pi.

Verdict

TimeTagger is the best choice for individuals and small teams who want simple, flexible time tracking without the overhead of project management features. Its tag-based approach is more intuitive than Kimai’s project/activity hierarchy, and it uses a fraction of the resources. If you need invoicing, team management, or client billing, Kimai is the better fit. For pure time tracking with a beautiful timeline interface, TimeTagger is unmatched.

Frequently Asked Questions

How does TimeTagger compare to Kimai?

TimeTagger is simpler — tag-based tracking with a drag-and-drop timeline, no projects or clients to set up first. Kimai is more structured with projects, activities, clients, invoicing, and team management. Choose TimeTagger for individual or small-team time tracking. Choose Kimai if you need client billing, invoicing, or multi-team management.

Does TimeTagger have a mobile app?

There’s no native mobile app, but the web interface is responsive and works well in mobile browsers. You can add it to your home screen as a PWA (Progressive Web App) for an app-like experience. The timeline interface adapts to smaller screens.

Can I export my time data?

Yes. TimeTagger supports exporting time entries as CSV and PDF reports. You can filter by date range and tags before exporting. The CSV export includes all entry details — start time, end time, duration, and tags — making it easy to import into spreadsheets or other tools.

Is there an API for integrations?

Yes. TimeTagger has a REST API that allows you to read and write time entries programmatically. This enables integration with automation tools like n8n or custom scripts. The API uses the same authentication as the web interface.

Can multiple users track time independently?

Yes. Add multiple user credentials in the TIMETAGGER_CREDENTIALS environment variable, separated by commas. Each user gets their own isolated time tracking data — they can only see and manage their own entries, not other users’ data.

Does TimeTagger support setting daily or weekly time goals?

Yes. You can set time targets (daily or weekly) and TimeTagger shows your progress against them on the timeline view. This is useful for freelancers tracking billable hours or anyone trying to hit minimum work hour targets.

Comments