Deploy Kimai — Self-Hosted Time Tracker & Invoicing
Self-host Kimai — track billable hours, no per-seat fees
MySQL
Just deployed
/var/lib/mysql
Kimai
Just deployed
/opt/kimai/var
Deploy and Host Kimai on Railway
Kimai is the #1 open-source time tracker — a self-hosted alternative to Toggl and Harvest with timesheets, projects, customers, activities, reports, and invoicing built in. Freelancers, agencies, and teams use it to track billable hours and turn them into invoices, without per-user subscriptions. This template deploys the official Kimai image wired to a Railway MySQL service, with the Apache and connection-string gotchas already solved and a strong admin account generated, so you're tracking time and billing clients in minutes.
What This Template Deploys
| Service | Purpose |
|---|---|
| Kimai | The time-tracking app, reports, and invoicing (PHP on Apache) |
| MySQL | Timesheets, customers, projects, users, and invoices |
Both connect over Railway's private network. A persistent volume at /opt/kimai/var holds plugins, sessions, and the install marker, while all your tracking data lives in MySQL — so nothing is lost on redeploy.
About Hosting
Kimai is a mature, capable app, and a few Railway-specific details decide whether it deploys cleanly — all handled here.
The DATABASE_URL needs the exact server version. Kimai's connection string isn't just host and credentials — it includes ?charset=utf8mb4&serverVersion=X, and that server version must match your actual MySQL version, or Kimai throws errors on migrations and queries. This is the most common Kimai setup mistake. This template builds the DATABASE_URL with the correct charset and server version for the provisioned MySQL, so it connects and migrates cleanly on first deploy.
The Apache MPM workaround is applied. Kimai's official image runs PHP on Apache, and php:*-apache images need an MPM-prefork configuration fix to run correctly on Railway. This template pre-applies that workaround, so the web server starts properly instead of failing — the same class of issue that trips up any Apache-based app on the platform.
TRUSTED_HOSTS and TRUSTED_PROXIES must match Railway. Kimai validates incoming requests against TRUSTED_HOSTS (your Railway domain) and needs TRUSTED_PROXIES set for Railway's edge proxy, or it rejects requests or generates wrong URLs. This template configures both for your deployment.
Your admin account and secret are generated. ADMINMAIL and ADMINPASS create your administrator on first boot, and a strong 32-character APP_SECRET is generated to encrypt sessions — keep it stable, since changing it logs everyone out. After deploy, open your Railway URL, land on /en/login, and sign in with the generated admin credentials from the Variables tab.
Data and plugins persist correctly. All tracking data — timesheets, customers, projects, invoices — lives in MySQL, while plugins, sessions, and the install marker persist on the /opt/kimai/var volume. Both survive redeploys. Point MAILER_URL at your SMTP provider so resets and invoice emails work.
Typical cost: ~$5–10/month on Railway for Kimai and MySQL — a small team often fits the hobby tier. Kimai is GPL-3.0 and free, with no per-user licensing versus Toggl and Harvest's per-seat fees.
How It Compares
| Kimai (self-hosted) | Toggl | Harvest | Clockify | |
|---|---|---|---|---|
| Cost model | Flat infra | Per user/month | Per user/month | Freemium + tiers |
| Invoicing | Built-in | Add-on | Yes | Add-on |
| Reports | Full, exportable | Yes | Yes | Yes |
| Data ownership | Full — your infra | Vendor | Vendor | Vendor |
| Multi-user teams | Yes, unlimited | Per seat | Per seat | Per seat |
| Self-hostable | Yes | No | No | No |
Toggl and Harvest are polished but bill per user every month and hold your data. Clockify has a free tier but gates features and keeps your data on its servers. Kimai's edge is a complete, professional time-tracking and invoicing suite — unlimited users, full reports, customer and project management — self-hosted at flat cost, so your billable-hours data stays on infrastructure you own and your bill doesn't grow with your team.
Deploy in Under 5 Minutes
- Click Deploy on Railway — Kimai and MySQL build and wire together (~4 minutes)
- Confirm
DATABASE_URL(with the correct serverVersion),APP_SECRET, andTRUSTED_HOSTSare set - Note the generated
ADMINMAILandADMINPASSin the Kimai service Variables tab - Open your Railway URL, go to
/en/login, and sign in with the admin credentials - Create a customer, add a project and activities, and start the timer from the top bar
Point MAILER_URL at your SMTP provider so password resets and invoice exports send.
Common Use Cases
- Freelance time tracking — log billable hours per client and project, then generate invoices
- Agency billing — track a whole team's time across customers with exportable reports
- Project cost tracking — see time and cost per project to manage budgets and profitability
- Data-sovereign timesheets — keep client and billing data on your own infrastructure
Configuration
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Auto-built | MySQL connection with the correct charset and serverVersion |
APP_SECRET | Generated | 32-char secret encrypting sessions — keep stable |
ADMINMAIL | Required | Administrator email — creates the admin on first boot |
ADMINPASS | Generated | Administrator password — visible in the Variables tab |
TRUSTED_HOSTS | Required | Your Railway domain, so Kimai accepts requests |
TRUSTED_PROXIES | Pre-set | For Railway's edge proxy |
MAILER_URL | Optional | SMTP for password resets and invoice emails |
The
DATABASE_URLserver version must be correct. Kimai's connection string includesserverVersion, which must match your MySQL, or migrations fail — the top Kimai setup error. This template builds it correctly, and applies the Apache MPM workaround so the server starts.
Set
TRUSTED_HOSTSand keepAPP_SECRETstable.TRUSTED_HOSTSmust be your Railway domain or requests are rejected; changingAPP_SECRETlogs everyone out. Both are configured at deploy.
Dependencies for Kimai Hosting
- Railway account — ~$5–10/month for Kimai and MySQL; a small team fits the hobby tier
- MySQL (included and wired with the correct connection string)
- A persistent volume at
/opt/kimai/varfor plugins and sessions (included) - Optional: SMTP credentials for password resets and invoice emails
Deployment Dependencies
Implementation Details
The template deploys the official kimai/kimai2:apache image (PHP on Apache) wired to a Railway-managed MySQL service over the private network. It builds the DATABASE_URL with the correct charset=utf8mb4 and a serverVersion matching the provisioned MySQL — a required detail, since a mismatched server version causes migration and query errors, and it is the most common self-hosted Kimai failure. It also pre-applies the php:*-apache MPM-prefork workaround needed to run Apache correctly on Railway.
TRUSTED_HOSTS is set to the Railway domain and TRUSTED_PROXIES for the edge proxy, so Kimai accepts requests and generates correct URLs. A strong APP_SECRET (which encrypts sessions and must remain stable) and the ADMINMAIL / ADMINPASS administrator account are generated on first boot, after which login is available at /en/login.
A persistent volume at /opt/kimai/var retains plugins, sessions, and the install marker across redeploys, while all timesheets, customers, projects, and invoices persist in MySQL — the component to back up. MAILER_URL can be pointed at an SMTP provider for password resets and invoice emails. Pin a specific Kimai release by setting the image tag in the service settings.
Frequently Asked Questions
Why does Kimai fail to connect or migrate? Almost always the DATABASE_URL server version — it must match your MySQL version, or migrations error. This template builds the connection string with the correct charset and server version, so it connects cleanly.
Where do I find my admin login? In the Kimai service Variables tab — ADMINMAIL and the generated ADMINPASS. Open your Railway URL, go to /en/login, and sign in.
Does my tracking data persist? Yes — timesheets, customers, projects, and invoices live in MySQL, and plugins and sessions on the /opt/kimai/var volume. Both survive redeploys; back up MySQL to preserve your records.
Can I generate invoices? Yes — Kimai includes invoicing built in, turning tracked hours into invoices you can export. Configure MAILER_URL so invoice emails and password resets send.
How many users can I add? Unlimited — Kimai has no per-user licensing, so you can add your whole team without per-seat fees, unlike Toggl or Harvest.
Why must TRUSTED_HOSTS match my domain? Kimai validates requests against it, so if it doesn't match your Railway domain, requests are rejected. This template sets it for your deployment.
Why Deploy Kimai on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Kimai on Railway you get a professional time tracker with the hard parts solved — MySQL wired with the correct connection string, the Apache workaround applied, trusted hosts set, and a strong admin account generated. Track billable hours and invoice clients, self-hosted with your data on infrastructure you own.
Template Content
MySQL
mysql:9.4Kimai
kimai/kimai2:apacheADMINMAIL
Bootstrap admin email (first deploy only)
ADMINPASS
Bootstrap admin password (first deploy only)
