LeaveFlow is a self-hosted, open-source leave management tool for small and medium-sized businesses. It handles leave requests, approvals, team calendars, entitlements, and GDPR-compliant data lifecycle — with first-class support for German labor law (Bundesurlaubsgesetz, federal state holidays, eAU).
License: PolyForm Noncommercial License 1.0.0 — free for non-commercial use, self-hosting permitted.
| Feature | Details |
|---|---|
| Leave requests | Full-day and half-day, Turbo Frame live preview, balance guard |
| Approval workflow | Symfony Workflow Component, 7 transitions, audit trail |
| Team calendar | FullCalendar.js, department filters, blackout periods |
| Entitlements | Regular + carryover, FIFO consumption, year transition |
| Holiday engine | All 16 German federal states, easter calculation, company overrides |
| Notifications | In-app + email, Slack, Microsoft Teams |
| Auth adapters | Local + 2FA (TOTP), Google Workspace, Microsoft Entra ID, LDAP/AD |
| Reports & exports | Statistics dashboard, CSV, PDF, iCal subscription feeds |
| GDPR lifecycle | Retention periods, anonymization, employee exit workflow |
| REST API | Bearer token authentication, OpenAPI/Swagger documentation |
| Component | Version |
|---|---|
| Docker | 24+ |
| Docker Compose | v2.20+ |
| MariaDB | 11.4 (included in Docker image) |
| PHP | 8.4 (included in Docker image) |
LeaveFlow ships as a Docker-first application. No local PHP or MariaDB installation required.
git clone https://github.com/markus-michalski/leaveflow.git
cd leaveflow
cp .env .env.local
Edit .env.local and set at minimum:
# Database password (change this!)
DATABASE_URL="mysql://app:YOUR_PASSWORD@database:3306/app?serverVersion=11.4.2-MariaDB&charset=utf8mb4"
# Email delivery
MAILER_DSN="smtp://your-smtp-server:587"
# Application URL (used in emails and iCal links)
APP_URL="https://leaveflow.your-domain.com"
docker compose up -d
The application starts on port 80 by default. Set SERVER_NAME=:8080 in .env.local to change the port.
docker compose exec -u app app php bin/console doctrine:migrations:migrate --no-interaction
Open http://localhost (or your configured domain) in a browser. The first-run wizard appears automatically when no company exists. It runs a pre-flight check (PHP version, extensions, database, migrations, writable directories) and guides you through creating the initial company and admin account.
Once the wizard completes, the app redirects to the login page. The wizard is strictly one-shot — it cannot be re-entered after a company record exists.
LeaveFlow has three roles. Each role has its own navigation area:
| Role | Path | Responsibilities |
|---|---|---|
ROLE_ADMIN |
/admin/... |
Full configuration: users, departments, absence types, entitlements, holidays, auth, statistics, API tokens |
ROLE_MANAGER |
/manager/... |
Approve/reject leave requests, manage team calendar and blackout periods |
ROLE_EMPLOYEE |
/my/... |
Submit leave requests, view balance, manage profile and subscriptions |
An admin can also act as a manager. Every user with an employee record can submit leave requests.
# Start all containers (app, database, mailer, openldap)
docker compose up -d
# Run migrations
docker compose exec -u app app php bin/console doctrine:migrations:migrate --no-interaction
# Load dev fixtures (demo company + test accounts)
make fixtures
# Run tests
make test
# Static analysis
make stan
Dev test accounts (after make fixtures):
| Password | Role | |
|---|---|---|
admin@leaveflow.test |
leaveflow-dev |
Admin |
manager@leaveflow.test |
leaveflow-dev |
Manager |
employee@leaveflow.test |
leaveflow-dev |
Employee |
Mailpit (email catcher) is available at http://localhost:8025.
LeaveFlow is licensed under the PolyForm Noncommercial License 1.0.0. Commercial use requires a separate agreement.
Contributions require signing the Contributor License Agreement. See CONTRIBUTING.md for the development workflow.
Issues and feature requests: GitHub Issues