Install Kimai in Docker
Zitat von mpachmann am 19. August 2025, 16:48 Uhrhttps://sliplane.io/blog/self-hosting-kimai-with-docker-on-ubuntu
Self-hosting Kimai with Docker on an Ubuntu server
What is Kimai?
Kimai is a powerful, open-source time tracking solution that helps teams and freelancers manage their work hours efficiently. With its intuitive interface and robust feature set, Kimai has become a popular choice for businesses looking to maintain control over their time tracking data. Here's what makes Kimai stand out:
- Open Source: Kimai is completely free and open-source, giving you full control over your data and customization options
- Multi-user Support: Perfect for teams of any size, with role-based access control
- Project Management: Organize time entries by projects, customers, and activities
- Invoicing: Generate professional invoices based on tracked time
- Reporting: Create detailed reports and export data in various formats
- API Access: Integrate with other tools through a stable API
- Mobile Friendly: Access your time tracking from any device with a modern browser
- Plugin System: Extend functionality with community-developed plugins
From freelancers tracking billable hours to team managers monitoring project progress and business owners overseeing multiple projects, Kimai offers great time tracking without the recurring costs of commercial solutions. Its self-hosted nature means you maintain compflete control over your data while avoiding monthly subscription fees.
0. Your Server
We'll use a Hetzner Cloud VPS as the base. It's affordable, fast, and easy to automate. Choose the following specs:
- OS: Ubuntu 24.04
- CPU: 2 vCPU
- RAM: 4 GB
- Storage: 40 GB SSD or more
- Network: IPv4 + IPv6
- Backups: Enable auto-backups
These specifications are chosen for a reason:
- 2 vCPUs provide enough processing power for Kimai and its database
- 4GB RAM ensures smooth operation even with multiple users
- 40GB SSD gives plenty of space for the application, database, and logs
- IPv4 + IPv6 ensures maximum compatibility
- Auto-backups protect your data from hardware failures
This should be enough for a basic setup. You can always scale up later if needed!
Create your server through the Hetzner Cloud console. If you don't have an account, use my referral link to get €20 in credit.
Make sure to add your SSH key during creation so you can log in securely from your machine.
1. Basic Setup
SSH into the server:
ssh root@your-server-ip
Update the system:
sudo apt-get update sudo apt-get upgrade -y
This ensures you have the latest security patches. Regular updates are crucial for server security as they patch known vulnerabilities and improve system stability.
2. Install Docker and Docker Compose
Docker allows us to run Kimai in an isolated container, making it easier to manage and update. Docker Compose helps us orchestrate multiple containers (Kimai and MySQL) together.
Install dependencies:
sudo apt-get install ca-certificates curl gnupg
Add Docker's GPG key:
sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg
Add the Docker repository:
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" \ | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker and Compose plugin:
sudo apt-get update sudo apt-get install docker-ce docker-ce-cli \ containerd.io docker-buildx-plugin docker-compose-plugin -y
Test your Docker setup:
sudo docker run hello-world
If that prints a success message, you're good to go.
3. Install Caddy for HTTPS
A reverse proxy like Caddy serves several important purposes:
- It handles SSL/TLS certificates automatically
- It provides an additional security layer between the internet and your application
- It can handle multiple applications on the same server
- It manages HTTP to HTTPS redirection
Instead of fiddling with Certbot and Nginx, we'll use Caddy. It automatically gets TLS certificates and renews them.
Install Caddy:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \ | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \ | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy -y
Caddy will run as a service automatically.
Edit the config:
sudo nano /etc/caddy/Caddyfile
Set up a reverse proxy:
yourdomain.com { reverse_proxy localhost:8001 }
Replace
yourdomain.com
with your actual domain. Make sure you've pointed your domain's A/AAAA records to your server IP before continuing.Restart Caddy to apply:
sudo systemctl restart caddy
Now any traffic to
https://yourdomain.com
will be routed to the Kimai container.
4. Docker Compose Setup
Docker Compose helps us manage multiple containers that work together. In our case, we need:
- A MySQL database for storing Kimai's data
- The Kimai application itself
Create a directory:
mkdir -p ~/kimai && cd ~/kimai nano docker-compose.yml
Paste the following:
services: mysql: image: mysql:8.3 volumes: - mysql:/var/lib/mysql environment: - MYSQL_DATABASE=kimai - MYSQL_USER=kimaiuser - MYSQL_PASSWORD=useaverylongandsecurepassword - MYSQL_ROOT_PASSWORD=useaverylongandsecurepassword restart: unless-stopped healthcheck: test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost interval: 20s start_period: 10s timeout: 10s retries: 3 kimai: image: kimai/kimai2:apache volumes: - data:/opt/kimai/var/data - plugins:/opt/kimai/var/plugins ports: - 8001:8001 environment: - ADMINMAIL=admin@kimai.local - ADMINPASS=changemeplease - DATABASE_URL=mysql://kimaiuser:useaverylongandsecurepassword@mysql/kimai?charset=utf8mb4&serverVersion=8.3.0 restart: unless-stopped volumes: data: mysql: plugins:
The configuration includes:
- Persistent volumes for data storage
- Health checks for the database
- Automatic container restart
- Environment variables for configuration
Start the containers:
sudo docker compose up -d
Verify everything is running:
docker ps
You should see two containers: one for Kimai and one for MySQL.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ba933d132ed6 mysql:8.3 "docker-entrypoint.s…" 14 seconds ago Up 13 seconds (health: starting) 3306/tcp, 33060/tcp kimai-mysql-1 df1dbb0e58e4 kimai/kimai2:apache "docker-php-entrypoi…" About a minute ago Up 13 seconds (health: starting) 80/tcp, 0.0.0.0:8001->8001/tcp kimai-kimai-1
5. Access Kimai in Your Browser
Visit
https://yourdomain.com
You'll be prompted to log in with the email and password you set in the Compose file.
Once logged in, you'll land on the dashboard:
6. Keep It Secure
Running your own server means you're responsible for security. Here are the basics:
- Enable 2FA in Kimai - This adds an extra layer of security beyond passwords
- Use strong passwords - Weak passwords are the most common security vulnerability
- Update Docker images regularly - New versions often include security fixes
- Enable automatic OS updates or run
apt upgrade
frequently - Keep your system secure- Install Fail2ban to block brute-force attacks to your server - Prevents automated login attempts
- Monitor logs with
docker logs
andjournalctl -u caddy
- Helps detect and troubleshoot issues
7. Updating Kimai
Regular updates are important for security and new features. To upgrade to the latest Kimai image:
sudo docker compose pull sudo docker compose up -d
This pulls new images and restarts your containers. Your data stays intact because it's stored in Docker volumes. Make sure that the new Kimai version does not have any breaking changes.
8. Cost Comparison
Provider vCPU RAM Disk Monthly Cost Render.com 1 2 GB 40 GB ~$35 Fly.io 2 2 GB 40 GB ~$17–20 Railway 2 2 GB 40 GB ~$15–30 Sliplane.io 2 2 GB 40 GB ~€9.50 flat Hetzner Cloud (self-hosted) 2 2 GB 40 GB ~€5–10 If you're okay with doing the setup and updates yourself, self-hosting wins on price and privacy. You get full control over your data and can run other tools on the same server.
Plugins https://www.kimai.org/documentation/plugin-management.html
Path on DockerHOST: /var/lib/docker/volumes/kimai_plugins/_data
Copy the Plugins in the folder on the DockerHOST, they will be visible in DockerCONTAINER.
Refresh Cache https://www.kimai.org/documentation/cache.html
Must be done in Docker Container: docker exec -it kimai-kimai-1 bash
in the container change the folder to: /opt/kimai and run the command bin/console kimai:reload
https://sliplane.io/blog/self-hosting-kimai-with-docker-on-ubuntu
Self-hosting Kimai with Docker on an Ubuntu server
What is Kimai?
Kimai is a powerful, open-source time tracking solution that helps teams and freelancers manage their work hours efficiently. With its intuitive interface and robust feature set, Kimai has become a popular choice for businesses looking to maintain control over their time tracking data. Here's what makes Kimai stand out:
- Open Source: Kimai is completely free and open-source, giving you full control over your data and customization options
- Multi-user Support: Perfect for teams of any size, with role-based access control
- Project Management: Organize time entries by projects, customers, and activities
- Invoicing: Generate professional invoices based on tracked time
- Reporting: Create detailed reports and export data in various formats
- API Access: Integrate with other tools through a stable API
- Mobile Friendly: Access your time tracking from any device with a modern browser
- Plugin System: Extend functionality with community-developed plugins
From freelancers tracking billable hours to team managers monitoring project progress and business owners overseeing multiple projects, Kimai offers great time tracking without the recurring costs of commercial solutions. Its self-hosted nature means you maintain compflete control over your data while avoiding monthly subscription fees.
0. Your Server
We'll use a Hetzner Cloud VPS as the base. It's affordable, fast, and easy to automate. Choose the following specs:
- OS: Ubuntu 24.04
- CPU: 2 vCPU
- RAM: 4 GB
- Storage: 40 GB SSD or more
- Network: IPv4 + IPv6
- Backups: Enable auto-backups
These specifications are chosen for a reason:
- 2 vCPUs provide enough processing power for Kimai and its database
- 4GB RAM ensures smooth operation even with multiple users
- 40GB SSD gives plenty of space for the application, database, and logs
- IPv4 + IPv6 ensures maximum compatibility
- Auto-backups protect your data from hardware failures
This should be enough for a basic setup. You can always scale up later if needed!
Create your server through the Hetzner Cloud console. If you don't have an account, use my referral link to get €20 in credit.
Make sure to add your SSH key during creation so you can log in securely from your machine.
1. Basic Setup
SSH into the server:
ssh root@your-server-ip
Update the system:
sudo apt-get update
sudo apt-get upgrade -y
This ensures you have the latest security patches. Regular updates are crucial for server security as they patch known vulnerabilities and improve system stability.
2. Install Docker and Docker Compose
Docker allows us to run Kimai in an isolated container, making it easier to manage and update. Docker Compose helps us orchestrate multiple containers (Kimai and MySQL) together.
Install dependencies:
sudo apt-get install ca-certificates curl gnupg
Add Docker's GPG key:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
Add the Docker repository:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker and Compose plugin:
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli \
containerd.io docker-buildx-plugin docker-compose-plugin -y
Test your Docker setup:
sudo docker run hello-world
If that prints a success message, you're good to go.
3. Install Caddy for HTTPS
A reverse proxy like Caddy serves several important purposes:
- It handles SSL/TLS certificates automatically
- It provides an additional security layer between the internet and your application
- It can handle multiple applications on the same server
- It manages HTTP to HTTPS redirection
Instead of fiddling with Certbot and Nginx, we'll use Caddy. It automatically gets TLS certificates and renews them.
Install Caddy:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy -y
Caddy will run as a service automatically.
Edit the config:
sudo nano /etc/caddy/Caddyfile
Set up a reverse proxy:
yourdomain.com {
reverse_proxy localhost:8001
}
Replace yourdomain.com
with your actual domain. Make sure you've pointed your domain's A/AAAA records to your server IP before continuing.
Restart Caddy to apply:
sudo systemctl restart caddy
Now any traffic to https://yourdomain.com
will be routed to the Kimai container.
4. Docker Compose Setup
Docker Compose helps us manage multiple containers that work together. In our case, we need:
- A MySQL database for storing Kimai's data
- The Kimai application itself
Create a directory:
mkdir -p ~/kimai && cd ~/kimai
nano docker-compose.yml
Paste the following:
services:
mysql:
image: mysql:8.3
volumes:
- mysql:/var/lib/mysql
environment:
- MYSQL_DATABASE=kimai
- MYSQL_USER=kimaiuser
- MYSQL_PASSWORD=useaverylongandsecurepassword
- MYSQL_ROOT_PASSWORD=useaverylongandsecurepassword
restart: unless-stopped
healthcheck:
test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost
interval: 20s
start_period: 10s
timeout: 10s
retries: 3
kimai:
image: kimai/kimai2:apache
volumes:
- data:/opt/kimai/var/data
- plugins:/opt/kimai/var/plugins
ports:
- 8001:8001
environment:
- ADMINMAIL=admin@kimai.local
- ADMINPASS=changemeplease
- DATABASE_URL=mysql://kimaiuser:useaverylongandsecurepassword@mysql/kimai?charset=utf8mb4&serverVersion=8.3.0
restart: unless-stopped
volumes:
data:
mysql:
plugins:
The configuration includes:
- Persistent volumes for data storage
- Health checks for the database
- Automatic container restart
- Environment variables for configuration
Start the containers:
sudo docker compose up -d
Verify everything is running:
docker ps
You should see two containers: one for Kimai and one for MySQL.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba933d132ed6 mysql:8.3 "docker-entrypoint.s…" 14 seconds ago Up 13 seconds (health: starting) 3306/tcp, 33060/tcp kimai-mysql-1
df1dbb0e58e4 kimai/kimai2:apache "docker-php-entrypoi…" About a minute ago Up 13 seconds (health: starting) 80/tcp, 0.0.0.0:8001->8001/tcp kimai-kimai-1
5. Access Kimai in Your Browser
Visit https://yourdomain.com
You'll be prompted to log in with the email and password you set in the Compose file.
Once logged in, you'll land on the dashboard:
6. Keep It Secure
Running your own server means you're responsible for security. Here are the basics:
- Enable 2FA in Kimai - This adds an extra layer of security beyond passwords
- Use strong passwords - Weak passwords are the most common security vulnerability
- Update Docker images regularly - New versions often include security fixes
- Enable automatic OS updates or run
apt upgrade
frequently - Keep your system secure - Install Fail2ban to block brute-force attacks to your server - Prevents automated login attempts
- Monitor logs with
docker logs
andjournalctl -u caddy
- Helps detect and troubleshoot issues
7. Updating Kimai
Regular updates are important for security and new features. To upgrade to the latest Kimai image:
sudo docker compose pull
sudo docker compose up -d
This pulls new images and restarts your containers. Your data stays intact because it's stored in Docker volumes. Make sure that the new Kimai version does not have any breaking changes.
8. Cost Comparison
Provider | vCPU | RAM | Disk | Monthly Cost |
---|---|---|---|---|
Render.com | 1 | 2 GB | 40 GB | ~$35 |
Fly.io | 2 | 2 GB | 40 GB | ~$17–20 |
Railway | 2 | 2 GB | 40 GB | ~$15–30 |
Sliplane.io | 2 | 2 GB | 40 GB | ~€9.50 flat |
Hetzner Cloud (self-hosted) | 2 | 2 GB | 40 GB | ~€5–10 |
If you're okay with doing the setup and updates yourself, self-hosting wins on price and privacy. You get full control over your data and can run other tools on the same server.
Plugins https://www.kimai.org/documentation/plugin-management.html
Path on DockerHOST: /var/lib/docker/volumes/kimai_plugins/_data
Copy the Plugins in the folder on the DockerHOST, they will be visible in DockerCONTAINER.
Refresh Cache https://www.kimai.org/documentation/cache.html
Must be done in Docker Container: docker exec -it kimai-kimai-1 bash
in the container change the folder to: /opt/kimai and run the command bin/console kimai:reload