Installation
There are two routes. Both end at the same wizard.
The simple route needs nothing but FTP access and no command line. It is right below. If you have SSH and would rather unpack yourself, the second route is further down.
Allow 20 to 30 minutes if the server meets the requirements.
The full list of requirements is on its own page: System requirements. Check it first — both routes do check by themselves, but a server without the required extensions will not get far.
The installer is German-only. Neither the bootstrap nor the wizard has a language switch. The screenshots below therefore show German labels; this guide names each field so you can follow along.
The simple route: one file
upload install.php → open it in a browser → five questions → done
1. Get the file
<https://updates.octibiz.com/install.php>
The browser downloads it rather than displaying it. It is a single file of about 27 KB.
2. Upload it by FTP
Put it into the directory Octibiz is to run in. With most providers that is httpdocs, html or public_html.
3. Open it in a browser
https://your-domain.com/install.php
The page checks the server and names every missing requirement individually.

If something is missing it shows in red, together with what to do in the hosting panel. The most common case:

4. Click „Installation starten"
From here everything runs by itself: determine the version, download the package, verify the checksum, extract, put the files in place, prepare the wizard.

The package is around 90 MB and is fetched in chunks. If the connection drops, the next attempt resumes where it left off instead of starting over.
At the end the page forwards you to the wizard — without you entering any key. The file generates it itself and appends it to the address. Then it deletes itself.
Continue at The wizard.
Does your domain point at the project directory rather than at
public/? Theninstall.phpcreates a redirect so it works anyway. Cleaner is to point the domain at thepublic/subdirectory in your hosting panel — the redirect is only the fallback.
The SSH route
If you have a shell anyway, this is the more direct way.
What to have ready
- An empty database and a database user with full privileges on it, including
CREATE,ALTER
and INDEX. Alternatively a user allowed to create the database.
- The public address the system will be reachable at, including
https://. - The web server configured so the domain points at the
public/subdirectory. - SSH access for
setup.sh. On plain web hosting, file upload plus a one-off script call is
enough.
Upload and unpack
Octibiz ships as a pre-built package. PHP libraries and the built interface are included.
tar -xzf octibiz-1.0.0.tar.gz
cd octibiz
The domain's document root points at public/, not at the project directory. Ready-made templates ship with it: deploy/nginx.vhost.conf and deploy/apache.vhost.conf.
Important for nginx: the installer lives under
public/install/and needs its own location taking precedence over the general PHP block. Without it the server delivers the file's source code instead of executing it. The shipped template already has the block.
Run setup.sh
./setup.sh
The script checks the requirements, sets the write permissions and prints a link with a security token at the end:
https://os.example.de/install/?token=ab12cd34…
On your own server you can have the background services set up at the same time:
sudo ./setup.sh --root
Careful, known gap:
setup.shcurrently checks seven PHP extensions while the wizard requires nine. Ifredisorintlare missing,setup.shpasses green and you only get blocked in the browser. Check both yourself beforehand:php -m | grep -E '^(redis|intl)$'
The token is mandatory
Without a valid token the installer answers with 403. That is deliberate: an open installer on a reachable server is a takeover opportunity.
On the simple route above you never see this — install.php generates the token itself.

If you lost the link, read the token off the server and append it yourself:
cat var/install.token
The wizard
This is where both routes meet. Five steps, with the current one always visible at the top.
1 — System requirements
The wizard checks the environment and names every missing requirement individually instead of failing in general. Red dots have to be fixed, yellow ones are recommendations.

It checks PHP 8.4 or newer, nine mandatory extensions, three recommended ones, availability of proc_open(), a discoverable PHP command line of 8.4 or newer, and write access to the project directory, var, config/jwt and public/uploads.
Fix what is missing and click Erneut prüfen (check again) — the check reruns without starting over.
2 — Database and address

| Field | What goes in |
|---|---|
| Öffentliche Adresse (public address) | Including https://. Every generated link is derived from this |
| Datenbank-Host, Port | With most providers 127.0.0.1 or localhost and 3306 |
| Datenbankname | The empty database |
| Datenbank-Benutzer, Passwort | The user with full privileges on that database |
| Datenbank anlegen (create database) | Tick if the database does not exist yet and the user may create it |
Verbindung testen & weiter (test connection and continue) verifies access immediately. Only once it works do you move on.
The line PHP-CLI erkannt shows which command line was found. If the wizard finds none, an input field appears instead — enter the full path there, for example /usr/bin/php8.4.
3 — Services

Redis and mail delivery. You can accept the defaults; without Redis the database takes over the queues.
These values are not verified. They go into the configuration unchanged. A typo in the mail credentials only surfaces when the first mail fails to arrive.
This is also where a warning appears if your database version is below the released lines — as in the picture. The installation continues anyway; the version is deliberately not a blocker. But a release without security updates does not belong in production.
4 — Administrator

Your first account. The password must be at least 12 characters and match twice.
The account receives the system roles for login, administration and API and, where present, the GF/Admin role.
Beispieldaten (demo data) is optional. It is meant for a demo, not for production.
5 — Review and install

Every entry once more at a glance. The password deliberately does not appear here.
The run
After Installation starten the wizard works through the steps and shows each one.

In order, this happens:
| Step | What it does |
|---|---|
| Write configuration | Generates all security keys and creates .env.local with file mode 600 |
| Prepare application cache | Clears the cache |
| Create database | Only if you ticked the box |
| Generate JWT key pair | For authentication |
| Set up database schema | All migrations |
| Set up permissions and roles | The permission catalogue |
| Load standard data | Statuses, settings, lookups |
| Record plugin ownership | The basis for cleanly removing modules later |
| Create administrator account | Your access |
| Warm the application cache | Makes the first call fast |
If a step fails, the wizard names the step and its output and offers Erneut versuchen (try again). Fix the cause and restart — the steps tolerate a second run.
Done

The wizard now locks itself through the file var/install.lock and deletes the token.
Without a browser
The same procedure runs on the command line:
php bin/console app:install
Interactively the command asks for the same values. For an unattended installation every value can be passed in:
php bin/console app:install --no-interaction \
--app-url=https://os.example.de \
--db-host=127.0.0.1 --db-name=octibiz --db-user=octibiz --db-password=… \
--create-database \
--admin-name="First Last" --admin-email=admin@example.de --admin-password=… \
--mailer-from="Octibiz <noreply@example.de>"
Further options: --db-port, --redis-url, --mailer-dsn, --google-allowed-domains, --php-cli, --with-demo, --force.
Shorter: ./setup.sh --cli.
After the installation
These five points belong to it. Without them the system is set up but not operational.
1. Remove the installer. The lock file disables it, but the directory should go:
rm -rf public/install
2. Set up background processing. Without running workers the system sends no mail and runs no scheduled task. On your own server ./setup.sh --root has already done this; on managed hosting you register the ready-made scripts from deploy/cronjobs/. Details in background processing.
The scheduler consumer must run exactly ONCE per environment. If it runs twice, every time-driven process fires twice — recurring invoices, dunning runs, deadlines.
3. Set up backups. deploy/backup.sh daily via cron. See backup and restore.
4. Secure .env.local. It is the only file holding secrets. It belongs in the backup and never in version control. If APP_CREDENTIAL_KEY is lost, every stored credential for connected systems becomes unreadable — permanently.
5. Verify mail and login. Sign in with the administrator account and trigger a test mail.
Also recommended: HTTPS with a valid certificate, SPF, DKIM and DMARC per sending domain, and the update feed for system updates.
When it does not work
| What you see | What to do |
|---|---|
install.php reports a PHP version that is too old | Activate PHP 8.4 for this domain in the hosting panel. With many providers the setting is per domain, not per contract |
install.php reports no outbound HTTPS | The server may not reach the internet. Then the SSH route with a self-uploaded package is what remains |
| The download stalls | Reload the page and start again — it resumes where it left off |
| „Beim Auspacken ging der Platz aus" (out of space) | Around 1.1 GB is needed temporarily. Archive, extracted archive and files exist side by side for a moment |
| The browser shows PHP source instead of the wizard | The web server is missing the /install/ rule. Take the template from deploy/ |
| „🔒 Zugriffstoken erforderlich" | Read the token from var/install.token and append it to the address |
„Setup kann nicht starten … var/ ist nicht beschreibbar" | Grant write access to var/ |
| „Abhängigkeiten fehlen / vendor/ nicht gefunden" | No complete package was unpacked |
| „PHP-CLI nicht gefunden" | Give the full path, e.g. /usr/bin/php8.4, or PHP_BIN=… ./setup.sh |
| „Zugriff verweigert" on the connection test | Wrong username or password |
| „Datenbankserver nicht erreichbar" | Wrong host or port |
| „Datenbank existiert nicht" | Check the name or tick "create database". It can also mean the user lacks the privilege to see the database at all |
| „proc_open deaktiviert" | Remove it from disable_functions in php.ini |
| „Sicherheits-Token ungültig. Seite neu laden." | Session expired or a second browser tab. Reload the page |
| Migrations fail | The database user lacks CREATE, ALTER or INDEX |
| The wizard still appears after installing | Remove public/install/ and reload |
| The interface stays blank | The built interface directory is missing. It ships in the package; installing from source means building it |
Starting over
On the command line:
php bin/console app:install --force
Through the browser: delete var/install.lock and run ./setup.sh again. The existing database stays in place.
On a server with deployment automation,
var/install.lockhas to survive releases. If the file disappears, the system considers itself uninstalled and redirects every call to the wizard.
Next
- System requirements — the full list
- Background processing — workers and schedules
- Backup and restore
- Hardening and security
- System update