Skip to content

TimeTagger Open Source Software

TimeTagger Open Source Software

This section introduces TimeTagger, the open-source time tracking software that serves as the backend database for our asset tracking system. Learning this section will enable you to:

  • Understand what TimeTagger is and its key features
  • Install TimeTagger using Docker Compose
  • Configure TimeTagger with authentication credentials
  • Perform basic TimeTagger operations through the web UI

Before starting this section, ensure you have:

  • Docker and Docker Compose installed (see Chapter 07)
  • Basic understanding of REST APIs
  • A server or local machine with Docker support
  • Node-RED MQTT connection working (see Chapter 09)

TimeTagger is an open-source, self-hosted time tracking application developed by Sören Stelting. It provides:

  • Simple web interface: Clean, minimal UI for manual time tracking
  • REST API: Full CRUD operations for programmatic access
  • Self-hosted: Run on your own server (Docker or Python)
  • Privacy-focused: No cookies, no tracking, no external dependencies
  • Reporting: Built-in time analysis and filtering

Why TimeTagger for Asset Tracking?

TimeTagger provides the perfect backend for our RFID-based check-in system because:

FeatureBenefit for Asset Tracking
REST APIProgrammatic record creation from ESP32/Node-RED
Self-hostedData stays on-premises (privacy concern for factories)
Simple data modelStart/end timestamps, description, tags
Docker supportEasy deployment alongside other IoT services
TimeTagger Record Structure:
┌─────────────────────────────────────┐
│ Record Object │
├─────────────────────────────────────┤
│ key: "a1b2c3d4e5f6" │ ← Client-generated unique ID
│ t1: 1715942400 │ ← Start timestamp (Unix seconds)
│ t2: 1715944200 │ ← End timestamp (Unix seconds)
│ ds: "Worked on ESP32 project" │ ← Description
│ mt: 1715944200 │ ← Modified timestamp
│ st: 1715944200 │ ← Server timestamp (set by server)
│ hidden: false │ ← Soft-delete flag
└─────────────────────────────────────┘

Step 1: Create Docker Compose Configuration

Section titled “Step 1: Create Docker Compose Configuration”

TimeTagger can be deployed using Docker Compose alongside other IoT services:

version: '3.8'
services:
timetagger:
image: ghcr.io/almarklein/timetagger:latest
container_name: timetagger
ports:
- "8820:80" # External port 8820 → container port 80
volumes:
- ./timetagger/data:/data # Persistent data storage
environment:
- TIMETAGGER_BIND=0.0.0.0:80
- TIMETAGGER_DATA_DIR=/data
restart: unless-stopped

Configuration Notes:

  • Port 8820 is used externally to avoid conflicts with other services (Node-RED uses 1880)
  • Data is stored in ./timetagger/data for persistence
  • The restart: unless-stopped policy ensures auto-restart after system reboot

TimeTagger requires authentication credentials to be set before first use:

Terminal window
# 1. Create the data directory
mkdir -p ./timetagger/data
# 2. Generate credentials using an online password hash tool
# or use Python to generate the password hash:
python3 -c "
import hashlib
password = 'NoderedCourse2023' # Choose a strong password
hash = hashlib.sha256(password.encode()).hexdigest()
print(f'Password hash: {hash}')
"
# 3. Create credentials file
# Format: username:password_hash
cat > ./timetagger/credentials << EOF
admin:5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
EOF
# Note: The hash above is for password "password" — use a real password

⚠️ Important:

TimeTagger credentials file format requires special handling in Docker Compose because the YAML parser may interpret $ signs as variable interpolation:

Terminal window
# For password hashes containing $ signs (such as those from htpasswd),
# double all $ signs in the docker-compose.yml environment variables
# OR use Docker secrets instead of environment variables

Simplified credential setup:

Terminal window
# 1. Create credentials directory
mkdir -p ./timetagger
# 2. Create the password hash
# Visit: https://timetagger.app/credentials
# Enter username: admin
# Enter password: NoderedCourse2023
# Copy the generated hash
# 3. Save the credentials
echo 'admin:$2b$12$LJ3m4ys3Lk0TSwHnbfFkJekKfRMEOYR3HpNqGMs.bQk4ZxvgVqFxq' > ./timetagger/credentials
# 4. Ensure Docker Compose mounts this file
# Add to volumes section of timetagger service:
# - ./timetagger/credentials:/data/credentials
Terminal window
# Start TimeTagger container
docker-compose up -d timetagger
# Check container status
docker ps | grep timetagger
# Expected output:
# CONTAINER ID IMAGE STATUS PORTS
# abc123def456 ghcr.io/almarklein/timetagger:latest Up 2 minutes 0.0.0.0:8820->80/tcp
# View logs
docker logs timetagger -f
1. Open browser: http://localhost:8820
2. Login with credentials:
- Username: admin
- Password: [your chosen password]
3. You should see the TimeTagger dashboard:
┌──────────────────────────────────────┐
│ TimeTagger │
├──────────────────────────────────────┤
│ [Start new recording...] │
│ │
│ Today │
│ ├── ESP32 Course 1h 30m │
│ ├── Client Meeting 45m │
│ └── Code Review 30m │
│ │
│ This Week: 12h 45m │
└──────────────────────────────────────┘

Manual Time Entry:

  1. Click the input field at the top
  2. Enter a description (e.g., “Worked on ESP32 project”)
  3. Press Enter to start recording
  4. Click the stop button to end the recording

Using Tags for Filtering:

Terminal window
# Tags can be added with #hashtag syntax
# Example: "Developed MQTT module #ESP32 #NodeRED"
# Later, filter by tag:
# In TimeTagger web UI, use the filter dropdown to select tags

Viewing Reports:

TimeTagger Report Features:
├── Daily/Weekly/Monthly views
├── Tag-based filtering
├── CSV export
├── Timeline visualization
└── Total time calculations

Confirm TimeTagger is working correctly:

Terminal window
# 1. Verify container is running
curl -s http://localhost:8820 | head -5
# Expected: HTML content with TimeTagger UI
# 2. Verify API endpoints are accessible
curl -s http://localhost:8820/api/v2/info
# Expected: JSON with server info
# 3. Test authentication
curl -s -X POST http://localhost:8820/api/v2/info \
-H "Content-Type: application/json" \
-d '{"auth": "your-auth-token"}'

Symptom: Container exits immediately after starting

Cause: Incorrect permissions on data directory

Solution:

Terminal window
# Fix directory permissions
chmod 777 ./timetagger/data
# Check logs for specific errors
docker logs timetagger

Symptom: Login fails with “Invalid credentials”

Cause: Credentials file format incorrect

Solution:

Terminal window
# Regenerate credentials
# Use the official credential generator:
# 1. Visit https://timetagger.app/credentials
# 2. Enter desired username and password
# 3. Copy the generated line
# 4. Save to credentials file
# Verify credentials file exists
ls -la ./timetagger/credentials
cat ./timetagger/credentials

Symptom: Error “port 8820 is already in use”

Solution: Change the external port in docker-compose.yml

ports:
- "8822:80" # Use a different external port
  • Recommended: Use a strong, unique password for TimeTagger admin
  • Recommended: Store credentials as a Docker secret or environment file
  • Recommended: Set up regular backups of the TimeTagger data directory
  • Avoid: Exposing TimeTagger directly to the internet without HTTPS
  • Avoid: Using default passwords in production environments

If you prefer not to self-host, TimeTagger also offers a hosted plan:

FeatureSelf-Hosted (Docker)Hosted Plan
CostFree (server costs)~$3-4/month
Data ControlFull (on-premises)Data on provider servers
Setup Time~15 minutesInstant (sign up)
API AccessFullSame API
PrivacyMaximumProvider-dependent
  1. TimeTagger is an open-source, self-hosted time tracking solution with a REST API
  2. Docker deployment makes installation simple alongside other IoT services
  3. REST API enables programmatic record creation from Node-RED and ESP32
  4. Authentication is handled via credentials file with password hashing
  5. Data model uses start/end timestamps, description, and tags

Writing Date: 2026-05-17
Based on Source File: 校正版/10 Time recording witht RFID und TimeTagger.md
Target Audience: Alibaba.com IoT Pre-sales Engineer
Status: ✅ Completed