Kimai
Overview
Kimai is a popular open source, self-hosted time-tracking application for teams and freelancers. From an ordinary browser you record working hours against customers, projects and activities. You then turn those timesheets into invoices and exportable reports, control access with roles and teams, and keep every record private on infrastructure you control.
This SecureAnyCloud image serves Kimai 2.60.0, a Symfony application, behind nginx with PHP 8.3 FPM and OPcache on a hardened Ubuntu 24.04 LTS base, patched at build time. Kimai stores its data in a local MariaDB database, which Kimai recommends for production. The schema is migrated in the image, so the application is ready the moment the VM boots.
What you get:
- Kimai 2.60.0 served by nginx through the PHP 8.3 front controller, managed by systemd
- The Kimai web interface on
:80with a super administrator account required to sign in - A per-VM application secret, database password and administrator password, generated on first boot and recorded in a root-only file. No shared or default login ships in the image
- A local MariaDB database, the datastore Kimai recommends for production
- Two dedicated Azure data disks: the MariaDB data directory at
/var/lib/mysqland the Kimai application tree at/opt/kimai, each independently resizable nginx.service,php8.3-fpm.serviceandmariadb.serviceas enabled systemd units- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting size. Size up for larger teams and heavier concurrent use.
Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the web interface. Also allow 443/tcp if you terminate TLS on the VM. Kimai serves plain HTTP on port 80, so for production, terminate TLS in front of it with your own domain.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Kimai by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Review the two dedicated data disks on the Disks tab, then select Review + create and Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:kimai-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name kimai \
--image sac1647283583153:kimai-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardOpen port 80 for the web interface:
az vm open-port --resource-group <your-rg> --name kimai --port 80Step 3 - Confirm the services are running
SSH in as azureuser and confirm that nginx, PHP-FPM and MariaDB are active. nginx serves Kimai on port 80.
systemctl is-active nginx php8.3-fpm mariadbss -tlnp | grep ':80 ' | sed 's/ */ /g'Step 4 - Retrieve the per-VM administrator password
Every VM generates its own administrator password on first boot and writes it, along with the login user and URL, to a root-only credentials file. Read it with sudo:
sudo cat /root/kimai-credentials.txtSign in to Kimai with username admin and the kimai.admin.pass value from this file.
To prove the login works from the command line, establish an authenticated session with those credentials. A successful login reaches the dashboard, which no longer contains the sign-in form. A wrong password is bounced back to the sign-in form:
U=$(sudo grep '^kimai.admin.user=' /root/kimai-credentials.txt | cut -d= -f2-);
P=$(sudo grep '^kimai.admin.pass=' /root/kimai-credentials.txt | cut -d= -f2-);
CJ=$(mktemp);
LF=$(curl -s -c "$CJ" http://127.0.0.1/en/login);
T=$(printf '%s' "$LF" | grep -m1 -oE 'name="_csrf_token"[^>]*value="[^"]+"' | sed -E 's/.*value="([^"]+)".*/\1/'); curl -s -b "$CJ" -c "$CJ" -o /dev/null -L --data-urlencode "_csrf_token=$T" --data-urlencode "_username=$U" --data-urlencode "_password=$P" http://127.0.0.1/en/login_check;
BODY=$(curl -s -b "$CJ" -L http://127.0.0.1/); rm -f "$CJ"; case "$BODY" in *_password*) echo "login FAILED";; *) echo "login OK";; esacStep 5 - Sign in to Kimai
Browse to http://<vm-public-ip>/. Kimai opens on its sign-in screen. Enter username admin and the password from Step 4, then select Login.
Step 6 - The dashboard
After you sign in, you reach the Kimai dashboard. It summarises your recorded working time, your most recent timesheets and your active work. The large start button at the top punches you in against the selected project and activity, so you can begin tracking time straight away.
Step 7 - Record timesheets, customers, projects and activities
Kimai organises time into a customer, project and activity hierarchy. Before you record billable time, create a customer, add a project under that customer, and add one or more activities to the project. From the left-hand menu you can:
- Open Timesheet to start and stop time records, edit durations, and review the time you have logged.
- Open Customers to manage the clients you bill, including their address, currency and budget.
- Open Projects to manage the projects under each customer, with their own budgets, dates and teams.
- Open Activities to manage the kinds of work you record time against, either globally or per project.
- Open Invoices to turn recorded time into invoices, and Export to produce CSV, Excel and PDF reports.
To change the administrator password, select your user avatar at the top right of any page, choose Profile, open the Password tab, and set a new password.
Step 8 - Manage users, roles and teams
Kimai supports multiple users with role-based access control. As a super administrator, you can invite colleagues and control what they can see and do.
Open Users under the administration area to create accounts and assign roles (user, teamlead, administrator, super administrator). Open Teams to group users and grant a team access to specific customers, projects and activities, so each person only sees the work that concerns them.
You can also create users from the command line on the VM. The console command prompts interactively for a password, so run it directly in your own terminal:
sudo -u www-data php /opt/kimai/bin/console kimai:user:create alice alice@example.com ROLE_ADMINStep 9 - Verify the stack
Confirm the Kimai version, that the services are enabled, and that the web interface answers on port 80:
sudo -u www-data php /opt/kimai/bin/console kimai:versionsystemctl is-enabled nginx php8.3-fpm mariadbcurl -s -o /dev/null -w 'Kimai login HTTP %{http_code}\n' http://127.0.0.1/en/loginStep 10 - Where your data lives
The MariaDB data directory and the Kimai application tree each live on their own dedicated Azure data disk, separate from the OS disk. The database is at /var/lib/mysql. The code, .env configuration and var/ runtime data are at /opt/kimai. Both disks are captured into the image and re-provisioned on every VM, and you can resize either tier independently. Confirm the mounts and filesystems:
df -h /var/lib/mysql /opt/kimai | tail -2for m in /var/lib/mysql /opt/kimai; do findmnt -no SOURCE,TARGET,FSTYPE "$m"; doneStep 11 - Enable HTTPS with Let's Encrypt
The image serves Kimai over HTTP on port 80 so it works immediately behind the VM's public address. For production, put it behind HTTPS. Point a DNS name at the VM and open 443/tcp in the NSG. Then install Certbot and request a certificate, replacing your-domain.example.com with the DNS name that resolves to the VM:
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.comCertbot obtains a certificate, updates the nginx configuration to serve Kimai over HTTPS, and sets up automatic renewal.
Step 12 - Back up and maintain your VM
All of Kimai's data is in the MariaDB database on the /var/lib/mysql disk and the application tree on the /opt/kimai disk. To back up your time-tracking data, snapshot the two Azure data disks from the portal or the CLI, or take a logical database dump:
sudo mariadb-dump kimai > /tmp/kimai-backup.sqlApply operating system security updates regularly. The image is patched at build time and ships with unattended security upgrades enabled. Because the data lives on its own disks, you can resize either tier independently if your time-tracking store grows.
Security notes
- Encrypt web traffic. Kimai serves plain HTTP on port 80. For production, put it behind your own TLS-terminating reverse proxy or an Azure Application Gateway with a certificate for your domain, and restrict port 80 in the NSG to trusted networks.
- Protect the administrator password. The per-VM administrator password lives in
/root/kimai-credentials.txt, readable only by root. The application secret and database password are rotated on first boot too, so no shared or default credential ships in the image. Sign in and change the administrator password from the profile menu, and keep a copy somewhere safe. - Use API tokens and single sign-on. Kimai exposes a full REST API and supports LDAP and SAML single sign-on. Create scoped API tokens or wire up your identity provider for integrations rather than sharing your login.
- Keep the VM patched. The image is patched at build time and ships with unattended security upgrades enabled.
Architecture summary
- Application: Kimai 2.60.0 (Symfony)
- Web server: nginx serving the public/ document root on port 80
- Runtime: PHP 8.3 FPM with OPcache
- Database: MariaDB, data directory on a dedicated data disk at /var/lib/mysql
- Application disk: dedicated data disk mounted at /opt/kimai (code, .env, var/)
- Credentials: generated on first boot, written to /root/kimai-credentials.txt (mode 0600)
- First user: the administrator is a super administrator of the installation
Support
SecureAnyCloud images come with 24/7 support. For questions about this Kimai image or help with your deployment, contact us through the SecureAnyCloud website.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on Azure
Launch Kimai on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Kimai is an open source, self-hosted time-tracking application. Teams and freelancers use it to record working hours against customers, projects and activities, then turn those timesheets into invoices and exportable reports. You punch in and out from the browser or the API, organise work into a clean customer, project and activity hierarchy, control access with roles and teams, and keep every record private on infrastructure you control.
This image runs Kimai, a Symfony application, behind nginx with PHP FPM 8.3 and OPcache enabled. Kimai stores its data in a local MariaDB database, which Kimai recommends for production deployments. The database schema is migrated in the image, so Kimai is ready the moment the instance boots.
What you get:
- A dedicated, independently resizable EBS volume mounted at
/var/lib/mysqlfor the MariaDB data directory - A second dedicated volume mounted at
/opt/kimaifor the Kimai application code, configuration andvar/runtime data, so you can grow either tier without touching the operating system disk - An application secret generated on the first boot of every deployed instance, a rotated database password and a fresh administrator password
- No shared credentials: two instances launched from the same Amazon Machine Image never share credentials
- The administrator username and password written to
/root/kimai-credentials.txtwith mode 0600, so that only the root user can read the file
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and inbound ports 80 and 443 from the networks your users will reach Kimai from
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Launch the instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and choose Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Kimai. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login).
Under Network settings, select your VPC and subnet. Create or select a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your users will use. Leave the root and data volumes at their default sizes or larger.
Choose Launch instance. First-boot initialisation takes approximately one minute after the instance state becomes Running and the status checks pass.
Launch the instance from the AWS CLI
The following command launches an instance from the SecureAnyCloud Kimai Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22, 80 and 443 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":20,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=kimai-01}]'On success, the command prints a JSON document. Note the instance ID, then retrieve the instance's public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Connect and retrieve the initial credentials
Connect over SSH with the key pair you selected and the public IP address from Step 2. The SSH login user depends on the operating system of the AMI variant you launched. For the Ubuntu 24.04 variant, the login user is ubuntu.
For the Ubuntu 24.04 variant, connect with ssh -i <path-to-key.pem> ubuntu@<instance-public-ip>.
Kimai generates a unique administrator password on first boot and writes it, along with the administrator username, to a root-only file. Retrieve it with:
sudo cat /root/kimai-credentials.txtThe file lists the administrator username (admin), the generated password and the instance URL. This account is a super administrator of the Kimai installation. Keep these credentials somewhere safe, and change the password after your first sign-in.
Use the following checks to confirm that the web server, PHP FPM and database are running, that the data volumes are mounted, and that Kimai answers on port 80:
systemctl is-active nginx php8.3-fpm mariadbdf -h /var/lib/mysql /opt/kimai | tail -2curl -s -o /dev/null -w 'Kimai login HTTP %{http_code}\n' http://127.0.0.1/en/loginEach command should report the services as active, show the dedicated data volumes mounted at /var/lib/mysql and /opt/kimai, and return HTTP 200 for the login page.
Sign in to Kimai
Open a web browser and browse to the instance address:
http://<instance-public-ip>/You are taken to the Kimai sign-in page. Enter the administrator username and the password from /root/kimai-credentials.txt and select Login.
After you sign in, you reach the Kimai dashboard. It summarises your recorded working time, your most recent timesheets and your active work. From here you can punch in to start tracking time straight away.
Record timesheets, customers, projects and activities
Kimai organises time into a customer, project and activity hierarchy. Before you can record billable time, create a customer, add a project under that customer, and add one or more activities to the project. From the left-hand menu you can:
- Open Timesheet to start and stop time records, edit durations, and review the time you have logged. The large start button at the top punches you in against the selected project and activity; punching out writes the duration to the timesheet.
- Open Customers to manage the clients you bill, including their address, currency and budget.
- Open Projects to manage the projects under each customer, with their own budgets, dates and teams.
- Open Activities to manage the kinds of work you record time against, either globally or per project.
- Open Invoices to turn recorded time into invoices using the bundled templates, and Export to produce CSV, Excel and PDF reports.
To change the administrator password, select your user avatar at the top right of any page, choose Profile, open the Password tab, and set a new password.
Manage users, roles and teams
Kimai supports multiple users with role-based access control. As a super administrator, you can invite colleagues and control what they can see and do.
- Open Users under the administration area to create user accounts and assign roles (user, teamlead, administrator, super administrator).
- Open Teams to group users and grant a team access to specific customers, projects and activities, so each person only sees the work that concerns them.
You can also create users from the command line on the instance. For example, to create an additional administrator, run the Kimai console as the web user. The command prompts interactively for a password, so run it directly in your terminal:
sudo -u www-data php /opt/kimai/bin/console kimai:user:create alice alice@example.com ROLE_ADMINThe command prompts for a password when one is not supplied. To change an existing user's password from the command line, use sudo -u www-data php /opt/kimai/bin/console kimai:user:password <username>.
Enable HTTPS with Let's Encrypt
The image serves Kimai over HTTP on port 80 so that it works immediately behind the instance's public address. For production, put it behind HTTPS. The simplest approach is to point a DNS name at the instance and use Certbot.
Install Certbot and the nginx plugin, then request a certificate for your domain. Replace your-domain.example.com with the DNS name that resolves to the instance:
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginxAfter the packages are installed, run sudo certbot --nginx -d your-domain.example.com and follow the prompts. Certbot obtains a certificate, updates the nginx configuration to serve Kimai over HTTPS, and sets up automatic renewal.
Back up and maintain your instance
All of Kimai's data is contained in the MariaDB database on the /var/lib/mysql volume and the application tree on the /opt/kimai volume. To back up your time-tracking data, either snapshot the EBS data volumes with the AWS Console or CLI, or take a logical database dump.
To take a logical backup of the database, use mariadb-dump on the instance:
sudo mariadb-dump kimai > /tmp/kimai-backup.sqlTo snapshot a data volume, find the volume ID attached to the instance and create a snapshot:
aws ec2 create-snapshot --volume-id <data-volume-id> --description "Kimai data backup"Apply operating system security updates regularly with sudo apt-get update && sudo apt-get upgrade. Because the data lives on its own volumes, you can resize them independently in the AWS Console if your time-tracking store grows.
Architecture summary
- Application: Kimai 2.60.0 (Symfony)
- Web server: nginx serving the public/ document root on port 80
- Runtime: PHP FPM 8.3 with OPcache
- Database: MariaDB, data directory on a dedicated EBS volume at /var/lib/mysql
- Application volume: dedicated EBS volume mounted at /opt/kimai (code, .env, var/)
- Credentials: generated on first boot, written to /root/kimai-credentials.txt (mode 0600)
- First user: the administrator is a super administrator of the installation
Support
This image is published and supported by SecureAnyCloud. Support covers Kimai deployment, upgrades, invoicing and exports, roles and teams, performance tuning, and database administration, 24/7 by email and chat. For help, contact SecureAnyCloud support through the channel listed on your AWS Marketplace subscription.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on AWS
Launch Kimai on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com