LeaveFlow: Installation
Installing LeaveFlow with Docker Compose: requirements, migrations, setup wizard, environment variables, HTTPS, update and development environment.
LeaveFlow: Installation
Requirements
You need Docker with the Compose plugin (docker compose) and Git. You do not have to install PHP or MariaDB yourself, the Compose stack provides both. The remaining requirements are on the overview page.
Installation
-
Clone the repository:
git clone https://github.com/markus-michalski/leaveflow.git cd leaveflow -
Start the containers (builds the image and starts the app, database, Mailpit and OpenLDAP):
docker compose up -d --buildOn the first start the container installs the Composer dependencies itself and builds the Tailwind stylesheet. This takes a moment, follow the progress with
docker compose logs -f app. -
Run the database migrations:
docker compose exec -u app app php bin/console doctrine:migrations:migrate --no-interaction -
Open the application in the browser:
http://localhost:8080. As long as no company exists, LeaveFlow redirects every page to the setup wizard at/setup.
The stack is a development stack:
compose.yamlbuilds the Docker targetdevand setsAPP_ENV: dev. The host ports come fromcompose.override.yaml(8080:80,8443:443, plus3306,1025and8025for the database and Mailpit). The Dockerfile also contains aprodtarget, but the repository does not ship a ready-made production Compose file.
Setup wizard
The wizard at /setup first checks the system requirements and then creates the company and the first admin.
| Check | What is checked |
|---|---|
| PHP version | PHP 8.4.0 or newer |
| PHP extensions | pdo_mysql, intl, gd, mbstring, json, curl, ctype, fileinfo |
| Database connection | Connection to the database |
| Database migrations | All migrations are applied |
| var directory | Directory var/ is writable |
| public/uploads directory | Directory public/uploads/ is writable |
While any check is red, the form cannot be submitted. The form asks for the company name, the admin email and an admin password of at least 12 characters. The wizard creates only the company and the admin account and runs once. Afterwards it shows the completion page at /setup/done with a list of next steps and the button Go to sign in, which leads to the sign-in page.
The wizard creates no absence types, locations, departments or employees. You do that afterwards in the admin menu, the order is described in the admin guide.
Configuration through environment variables
Symfony reads .env, .env.local and .env.dev. Environment variables that the container receives directly take precedence over all of these files.
compose.yamlhard-setsDATABASE_URL(with the password!ChangeMe!) andMAILER_DSN(smtp://mailer:1025) as container environment variables. Values from.env.localtherefore have no effect for these two variables. To change them, editcompose.yaml, and change the database password in all three places (MARIADB_PASSWORD,MARIADB_ROOT_PASSWORDandDATABASE_URL).
| Variable | Meaning |
|---|---|
APP_ENV |
Environment; compose.yaml sets dev |
APP_SECRET |
Secret for CSRF tokens and signatures, unique per installation. Empty in .env, .env.dev ships a value for development |
DATABASE_URL |
Database connection; the host in the stack is database |
MAILER_DSN |
Mail transport; smtp://mailer:1025 (Mailpit) in the stack |
MESSENGER_TRANSPORT_DSN |
Queue for asynchronous messages; default doctrine://default?auto_setup=0 |
DEFAULT_URI |
Base URL for links generated without a browser request (console commands, cron jobs, queued mails); default http://localhost:8080 |
SERVER_NAME |
Address the built-in web server listens on; default :80 |
APP_LDAP_ENCRYPTION_KEY |
32-byte key (Base64) used to encrypt stored credentials for LDAP and Slack |
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET |
OAuth credentials for Google sign-in |
ENTRA_CLIENT_ID, ENTRA_CLIENT_SECRET |
OAuth credentials for Microsoft sign-in |
ENTRA_TENANT_ID |
Tenant for Microsoft sign-in; default common |
There is no
APP_URLvariable. The base URL for links outside browser requests is set byDEFAULT_URI.
Docker Compose evaluates SERVER_NAME at start from the shell environment or from the .env in the project directory, not from .env.local. Generate the value for APP_LDAP_ENCRYPTION_KEY with:
php -r "echo base64_encode(random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES)) . PHP_EOL;"
Without this key, the Slack token, the Slack signing secret and the LDAP bind password cannot be saved. If you change the key later, values that were already stored can no longer be decrypted.
HTTPS and domain
The PHP configuration sets session cookies with session.cookie_secure = 1. Run the instance behind HTTPS outside localhost and set DEFAULT_URI to the public address. The built-in web server (Caddy in FrankenPHP) serves the address given in SERVER_NAME.
Update
git pull
docker compose up -d --build
make install
docker compose exec -u app app php bin/console doctrine:migrations:migrate --no-interaction
Once a company exists, the setup wizard no longer shows pending migrations. Apply them after every update.
Development environment
| Command | Effect |
|---|---|
make up / make down |
Start and stop the containers |
make test |
PHPUnit test suite |
make stan |
PHPStan |
make fixtures |
Empty the database and load demo data |
make fixturesempties the database completely before loading the demo data. Never run it against an instance with real data.
After make fixtures there is a demo company with locations, departments, employees, seven absence types and three test accounts.
| Password | Role | |
|---|---|---|
admin@leaveflow.test |
leaveflow-dev |
Administrator |
manager@leaveflow.test |
leaveflow-dev |
Manager |
employee@leaveflow.test |
leaveflow-dev |
Employee |
Mailpit, the email catcher of the stack, is available at http://localhost:8025.