Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Automating provisioning

A provisioning pipeline for new Exponential customer sites, step by step: system user and isolation, database, code from Git or Composer, exp:install with secrets from the environment, serving the site, cron, password…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/hosting/provisioning/automating-provisioning.md

On this page

Automating provisioning

This page is for system administrators and developers who automate the creation of Exponential customer sites. It answers: which steps a pipeline needs, in which order, what each step checks, and how a site is removed again. Your own tooling (panel hooks, configuration management, shell scripts) does the work; this page gives the Exponential side of each step.

Warning

.htaccess slows down every request. When .htaccess files are enabled (AllowOverride anything but None), let alone used, Apache looks for them and reads and evaluates them on every request, in every directory of the path, and page loading times go up drastically (measured). The only real fix is to switch the feature off for the virtual host: AllowOverride None in the HTTPS virtual host, and the rules in the virtual host's own configuration as mod_rewrite rules. That is far faster in production speed tests and well worth the time it takes to optimize a production configuration. Switch over right away: copy the rules of the example HTTPS virtual host into your virtual host (with the static cache, also staticcache_offload.conf), set AllowOverride None, run apachectl configtest, reload Apache and test the site. The same rules for other servers: nginx, LiteSpeed, Caddy, IIS, Velocity (built in); where virtual host rules go in a control panel: Plesk, cPanel, DirectAdmin, ISPConfig. On LiteSpeed or OpenLiteSpeed, the server's own page cache can also answer anonymous visitors and crawlers without PHP: Page caching with LiteSpeed and OpenLiteSpeed.

Contents

  1. The pipeline
  2. Step by step
  3. Making it safe to run again
  4. Removing a site
  5. A record per site

The pipeline

#StepChecks
1System user and directorythe user exists, the directory belongs to it
2PHP: FPM pool or Velocity instancethe pool or instance runs as that user
3Databaseempty database, user with create rights (not for SQLite 3)
4Codethe tested release is checked out, vendor/ complete
5Installexp:install --dry-run, then exp:install; exit status 0
6Servethe site answers over HTTPS
7Cronthe site user's crontab runs runcronjobs.php
8Handoverpassword delivered, var/log/initial-admin-password removed
9Backups and monitoringthe site is registered in both

Step by step

1. System user and directory

One system user per site (Per-customer users and pools). Everything the installer and the site write must belong to that user: "Run it as the user the web server or Velocity runs as, or fix the ownership afterwards" (4.6).

2. PHP

  • PHP-FPM: a pool for the site, running as its user (PHP-FPM tuning).
  • Velocity: workers run as [ServerSettings] User and Group of the site's velocity.ini; give each site its own ports (Velocity workers and pools).

3. Database

For SQLite 3, nothing but a writable var/storage/sqlite3/. For a server engine, create a database and a user for this site alone (Databases and users in panels); never reuse root or postgres.

4. Code

A checkout of the release tag you tested, then the dependencies from the lock file:

git clone --branch v6.0.<n> https://github.com/se7enxweb/exponential.git <installation>
cd <installation> && composer install --no-dev

Pin one release for all new sites and move the pin only after a test (Composer and Git on servers).

5. Install

Pass the database password through the environment and test first:

export EXP_INSTALL_DB_PASSWORD='<from your secret store>'
php bin/php/console exp:install --dry-run --db=pgsql --db-host=<db host> --db-name=<db> --db-user=<db user> \
  --url=https://www.example.com --email=<contact> --package=sevenx_multisite_clean
php bin/php/console exp:install --apply --db=pgsql --db-host=<db host> --db-name=<db> --db-user=<db user> \
  --url=https://www.example.com --email=<contact> --package=sevenx_multisite_clean

On exit status 1, keep var/log/setup.log and stop the pipeline; the site stays in maintenance mode (exp:install for hosts).

6. Serve

Configure the web server for the site, or set the Velocity engine and start it (Choosing a web server). Under Apache or LiteSpeed, put .htaccess into place, and config.php with the values this server needs, from the console. Run as root, every command needs --allow-root-user, and --owner gives a new file to the site's user:

php bin/php/console exp:setup:htaccess --apply --allow-root-user --owner=<site user>:<site group>
php bin/php/console exp:setup:config --apply --allow-root-user --owner=<site user>:<site group>
php bin/php/console exp:config:set EZP_DIR_MODE_MAX 0750 --apply --allow-root-user
php bin/php/console exp:config:set EZP_FILE_MODE_MAX 0640 --apply --allow-root-user
php bin/php/console exp:config:list --only-set --allow-root-user

Each command ends with PASS: or FAIL: and exits 0, 1 or 2; a second run says nothing to do (Setting up .htaccess and config.php from the console). Then check from outside:

curl -s -o /dev/null -w '%{http_code}\n' https://www.example.com/
curl -s -o /dev/null -w '%{http_code}\n' https://www.example.com/admin/user/login

Both should answer 200 (10.11).

7. Cron

Install the crontab of 10.3 in the site user's crontab, with the same PHP binary the web uses (Cron jobs).

8. Handover

If the password was generated, read it from var/log/initial-admin-password, deliver it through a secure channel and delete the file. Tell the customer to change it and create personal accounts (First sign-in and default passwords).

9. Backups and monitoring

Register the database and var/storage, settings/override, settings/siteaccess in the backup system, and the site's address in monitoring (What to back up, Health checks and uptime).

Making it safe to run again

  • Detect an existing installation the way exp:install does: settings/override/site.ini.append.php holds a [DatabaseSettings] block. Skip the install step when it does; exp:install itself refuses without --force.
  • Never pass --force from a pipeline unless the run is meant to destroy and rebuild that site.
  • Keep --db-action=remove away from databases with data. A pipeline should always create a new database for a new site.
  • Keep secrets out of logs. Do not echo the environment; the saved configuration in var/log/ masks passwords, and the exp:config:* commands print ******** for every password or key unless given --show-secrets. Pass a secret as --value="$VARIABLE", not typed on the command line.
  • .htaccess and config.php are safe to repeat. exp:setup:htaccess and exp:setup:config never replace a file that differs from its template without --force, and exp:config:set changes nothing when the value is already there. In a drift check, exp:setup:htaccess without --apply exits 1 when .htaccess has changed, and exp:config:list --only-set --format=json gives a document to compare.

Removing a site

The reverse order: maintenance mode on, a final backup, crontab removed, web server or Velocity instance removed, database and user dropped, files removed, backups kept for the agreed retention. The full list is the Customer offboarding checklist.

A record per site

Write what the pipeline did into a record per site: domain, system user, PHP version, engine and ports, database engine and name, release tag, site package, install date, backup and monitoring registration. Support staff need it on the first call.

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x