Self-Hosting Kimai with Docker Compose
What Is Kimai?
Kimai is a free, open-source time tracking application. It handles time sheets, project tracking, customer management, invoicing, and reporting — everything a freelancer or team needs to track billable hours. It replaces Toggl, Harvest, and Clockify with a self-hosted solution you fully control. Official site
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 1 GB of free RAM
- A domain name (recommended for HTTPS access)
Docker Compose Configuration
services:
kimai-db:
image: mysql:8.3
container_name: kimai-db
environment:
MYSQL_DATABASE: kimai
MYSQL_USER: kimai
MYSQL_PASSWORD: change-this-database-password
MYSQL_ROOT_PASSWORD: change-this-root-password
volumes:
- kimai-db:/var/lib/mysql
networks:
- kimai
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
kimai:
image: kimai/kimai2:apache-2.51.0
container_name: kimai
ports:
- "8001:8001"
environment:
# Admin account (created on first run)
ADMINMAIL: [email protected]
ADMINPASS: change-this-admin-password # CHANGE THIS
# Database connection
DATABASE_URL: mysql://kimai:change-this-database-password@kimai-db/kimai?charset=utf8mb4&serverVersion=8.3.0
# Application settings
TRUSTED_PROXIES: "0.0.0.0/0" # Set to reverse proxy IP in production
TRUSTED_HOSTS: "localhost,kimai.example.com"
volumes:
- kimai-data:/opt/kimai/var/data
- kimai-plugins:/opt/kimai/var/plugins
networks:
- kimai
depends_on:
kimai-db:
condition: service_healthy
restart: unless-stopped
networks:
kimai:
volumes:
kimai-db:
kimai-data:
kimai-plugins:
Start Kimai:
docker compose up -d
First startup takes 1-2 minutes for database migration. Access the web UI at http://your-server:8001 and log in with the admin credentials you set.
Initial Setup
After first login:
- Create customers — navigate to Admin → Customers. Each customer represents a client you bill.
- Create projects — under each customer, create projects. Projects organize work streams.
- Create activities — activities describe the type of work (development, design, meetings). They can be global or project-specific.
- Create team members — Admin → Users. Assign roles: User, Teamlead, Admin, or Super Admin.
- Start tracking — click the green play button to start a timer, or manually add time entries.
Features at a Glance
| Feature | Details |
|---|---|
| Time tracking | Start/stop timer, manual entry, calendar view |
| Projects & customers | Hierarchical organization |
| Teams | Assign members to projects, team-based reporting |
| Invoicing | Generate invoices from tracked time, multiple templates |
| Reporting | Daily, weekly, monthly reports with filtering |
| Export | CSV, PDF, XLSX, HTML exports |
| API | Full REST API for integrations |
| Plugins | Marketplace with 50+ plugins (expenses, vacation, approvals) |
| 2FA | TOTP-based two-factor authentication |
| LDAP/SAML | Enterprise authentication support |
Configuration
Timezone
Set the application timezone via environment variable:
environment:
APP_TIMEZONE: America/New_York
Memory Limit
For larger teams (20+ users), increase PHP memory:
environment:
memory_limit: 512M
Email Notifications
Configure SMTP for invoice delivery and password resets:
environment:
MAILER_URL: smtp://mail.example.com:587?encryption=tls&[email protected]&password=mail-password
MAILER_FROM: [email protected]
Invoicing
Kimai generates invoices directly from tracked time entries:
- Go to Invoices → select customer, date range, and entries
- Choose a template (built-in or custom DOCX/XLSX/PDF)
- Generate and download the invoice
- Entries are marked as invoiced to prevent double-billing
Custom invoice templates use Twig syntax — upload them to the var/invoices/ directory inside the container.
Reverse Proxy
Behind Nginx Proxy Manager:
Proxy Host: time.example.com → http://kimai:8001
Set TRUSTED_PROXIES and TRUSTED_HOSTS in your environment to match your proxy setup. Without this, Kimai may generate incorrect URLs.
Backup
Critical data to back up:
| Volume | Contains |
|---|---|
kimai-db | All time entries, customers, projects, users |
kimai-data | File uploads, custom templates |
kimai-plugins | Installed plugins |
# Database dump (preferred)
docker exec kimai-db mysqldump -u kimai -p'change-this-database-password' kimai > kimai-backup-$(date +%Y%m%d).sql
See Backup Strategy for automated approaches.
Troubleshooting
Login fails after first setup
Symptom: Admin credentials don’t work at the login page.
Fix: Database migration may not have completed. Check logs: docker logs kimai. If you see migration errors, ensure MySQL is healthy and restart: docker compose restart kimai.
”Trusted proxy” warnings in logs
Symptom: Kimai logs show “request not trusted” or URLs use HTTP instead of HTTPS.
Fix: Set TRUSTED_PROXIES to your reverse proxy IP or 0.0.0.0/0 (for Docker networks). Also set TRUSTED_HOSTS to your domain.
Slow performance with large datasets
Symptom: Reports and invoice generation slow down with 10,000+ entries.
Fix: Increase PHP memory_limit to 512M or 1G. Ensure MySQL has adequate innodb_buffer_pool_size (default may be too low).
Plugin installation fails
Symptom: Error when installing plugins from the marketplace.
Fix: Ensure the kimai-plugins volume is writable. Inside the container: docker exec kimai ls -la /opt/kimai/var/plugins/. Fix permissions if needed.
Resource Requirements
- RAM: ~200 MB idle (Kimai + MySQL), ~500 MB under load with 10+ concurrent users
- CPU: Low — PHP application with periodic report generation
- Disk: ~500 MB for application + database. Grows with file uploads.
Verdict
Kimai is the best self-hosted time tracker for freelancers and small teams. The invoicing integration sets it apart — track time and bill clients from the same tool. For enterprise teams needing approval workflows and advanced reporting, the plugin marketplace fills the gaps. If you need simpler time tracking without project management, look at Traggo as a lighter alternative.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments