Provisioning

When a new site is created, ProvisionSiteJob runs Provisioner::provision(), which performs seven steps in order. On failure, cleanup runs in reverse order.

Flow

sequenceDiagram participant User participant Job as ProvisionSiteJob participant P as Provisioner participant FS as Filesystem participant MySQL participant WP as WP-CLI participant Nginx User->>Job: Create site Job->>P: provision(site) P->>FS: ensureFilesystem P->>P: createSiteUser P->>MySQL: createDatabase P->>WP: installWordPress P->>WP: applyTemplate P->>P: installWphosterAgent P->>Nginx: configureNginx P->>P: configureCloudflare

Step breakdown

  1. ensureFilesystemmkdir -p site root, chmod 755. Path from config('wphoster.paths.sites_root').
  2. createSiteUserUserManager::createSiteUser() creates OS user; os_user and os_user_uid saved on site. File: app/Services/System/UserManager.php.
  3. createDatabase — MySQL CREATE DATABASE, CREATE USER, GRANT. Password stored encrypted in site.db_password_encrypted. Uses sudo mysql with stdin.
  4. installWordPress — Download WordPress zip (cached 24h in storage/app/tmp/wordpress-latest.zip), unzip to site root, wp config create, wp core install.
  5. applyTemplate — Install plugins/themes from site template (local path or repo slug), apply wp_option_overrides_json. File: app/Services/Provisioning/Provisioner.php (applyTemplate).
  6. installWphosterAgentWphosterAgentInstaller::install() rsyncs plugin from provisioning/wordpress/wphoster-agent, activates plugin, appends token to wp-config. File: app/Services/WordPress/WphosterAgentInstaller.php.
  7. configureNginx — Render provisioning/nginx/site.conf.stub with {{ server_name }}, {{ root_path }}, {{ php_fpm_socket }}; write to nginx_sites_available/{slug}.conf, symlink in nginx_sites_enabled, nginx -s reload.
  8. configureCloudflare — Upsert A record for site FQDN to config('wphoster.server_ip') (if Cloudflare enabled).

Key files

PathPurpose
app/Services/Provisioning/Provisioner.phpMain provisioning logic
app/Jobs/ProvisionSiteJob.phpQueue job that calls Provisioner
app/Services/System/UserManager.phpCreate/delete site OS user
app/Services/WordPress/WphosterAgentInstaller.phpInstall agent plugin and token
provisioning/nginx/site.conf.stubNginx vhost template

Cleanup on failure

cleanupOnFailure() runs in reverse order: Nginx config removed, database dropped, user deleted, filesystem removed. Cloudflare is not reverted (provisioning continues without failing if DNS fails).

Nginx template snippet

provisioning/nginx/site.conf.stub
server_name {{ server_name }};
root {{ root_path }};
fastcgi_pass {{ php_fpm_socket }};

Config keys

KeyPurpose
wphoster.paths.sites_rootBase directory for site roots
wphoster.paths.nginx_sites_availableNginx configs directory
wphoster.paths.nginx_sites_enabledNginx enabled symlinks
wphoster.php_fpm_socketPHP-FPM socket path
wphoster.mysql.hostMySQL host
wphoster.mysql.root_userMySQL root user for CREATE DATABASE
wphoster.wp_cli.pathWP-CLI binary path
wphoster.agent.enabledWhether to install WP Hoster Agent
wphoster.agent.pathPath to agent plugin source