Skip to main content

Provision

The provisioning process, handled by the provision.sh script, sets up a Drupal site on already assembled codebase by either importing an existing database from the dump or installing a fresh instance of Drupal using a profile, followed by running the necessary configuration import and database updates.

The main purpose of the script is to automate the setup of a Drupal site in every environment, ensuring consistency and eliminating manual steps.

Rationale

While Drush provides individual commands for deployment steps (such as drush updatedb, drush config:import, and drush deploy:hook), using them directly assumes the site is already in a bootstrapped, stable state. In practice, especially during initial setup or provisioning in dynamic environments (like CI pipelines, container builds, or multisite setups), additional orchestration is needed.

The provision.sh script addresses these gaps by:

  • Bootstrapping the environment: It can import a database dump or install a fresh Drupal instance from a profile.
  • Handling conditional logic: It accounts for different runtime scenarios, such as skipping provisioning, enforcing fresh database imports, or using maintenance mode.
  • Enforcing consistency: The same provisioning logic runs across local, CI, staging, and production environments, eliminating "it works on my machine" issues.
  • Supporting extensibility: It allows for custom post-provisioning scripts, making it easy to layer in project-specific logic like enabling test modules or running migrations.

In short, provision.sh orchestrates standalone Drush commands in a consistent, repeatable, and configurable process — turning a manual setup step into a reliable automation layer.

Database import vs full provisioning

Vortex provides two main approaches for setting up your database:

Full provisioning (ahoy provision)

Runs the complete provisioning process including:

  • Database import from dump or profile installation
  • Database updates via drush updatedb
  • Configuration import via drush config:import (if config files present)
  • Cache rebuilds
  • Deployment hooks
  • Post-provisioning custom scripts

Use this when you want a fully configured site ready for development or deployment.

# Full provisioning (recommended for most cases)
ahoy provision

Database import (ahoy import-db)

Imports only the database dump without running deployment scripts:

  • Imports the database dump
  • Skips configuration imports
  • Skips database updates
  • Skips post-provisioning scripts
# Import database only from default dump in .data/db.sql
ahoy import-db

# Import database only from a specific dump file
ahoy import-db path/to/dump.sql

When to use which command

Use ahoy import-db when you only need the raw database data without any configuration changes or updates.

Use ahoy provision when you want the full setup including configuration and updates.

Provisioning flow

Below is a generic provisioning flow diagram illustrating the steps taken by the provision.sh script. The flow may vary based on environment variables and conditions that could alter the execution path.

The numbered steps refer to the environment variables described in the next section.

🚀 Start

① 💡 Skip provision? ──Yes──► 🏁 End
│ No

② 💡 Provision type = database

├─ 💡 Existing site found = YES
│ ├─ Container image set? ──► preserve content (no change)
│ ├─ ③ Overwrite DB? ──Yes──► 🗑️ Drop DB ──► 🛢️ Attempt import from dump
│ │ │
│ │ ├─ Dump file exists? ──► 🛢️ Import DB
│ │ └─ Dump file missing?
│ │ ├─ ④ Fallback? ──Yes──► 📦 Install from profile ✓
│ │ └─ ④ Fallback? ──No───► 🏁 EXIT 1 (fail) ✗
│ └─ else ──► preserve content, ⑦ skip sanitization

└─ 💡 Existing site found = NO
├─ Container image set?
│ ├─ ④ Fallback? ──Yes──► 📦 Install from profile ✓
│ └─ ④ Fallback? ──No───► 🏁 EXIT 1 ("corrupted image") ✗
└─ Container image not set? ──► 🗑️ Drop DB ──► 🛢️ Attempt import from dump

├─ Dump file exists? ──► 🛢️ Import DB
└─ Dump file missing?
├─ ④ Fallback? ──Yes──► 📦 Install from profile ✓
└─ ④ Fallback? ──No───► 🏁 EXIT 1 (fail) ✗

── after provisioning (both DB and profile paths) ──

⑤ 💡 Skip other operations? ──Yes──► 🏁 End
│ No

⑥ 🚧 Enable maintenance mode

🔄 Run DB updates

⑦ 💡 Verify config unchanged? ──Config changed──► 🏁 EXIT 1 (fail) ✗
│ Config unchanged (or check disabled)

⬇️ Import configuration (if config files present)

🧹 Rebuild caches

🔄 Run deployment hooks

⑧ 😷 Run DB sanitization

⚙️ Run custom scripts

⑥ 🚧 Disable maintenance mode

🏁 End

Customizing flow

You can control the provisioning flow using the following environment variables:

  1. VORTEX_PROVISION_SKIP=1
    Kill-switch to completely skip provisioning. The script will exit immediately after start. Useful in emergencies when any kind of automation needs to be disabled.

  2. VORTEX_PROVISION_TYPE=profile
    Install from a Drupal profile instead of importing from a database dump. Useful for building sites without the persistent DB and/or test profile configuration installation.

  3. VORTEX_PROVISION_OVERRIDE_DB=1
    Drop an existing database before importing from dump/installing from profile. This is useful when an already provisioned environment requires a fresh database to be imported.

  4. VORTEX_PROVISION_FALLBACK_TO_PROFILE=1
    Automatically fall back to installing from profile if the database dump file or container image is not available. Useful for distribution demos or when using recipes/profiles that can install without a pre-existing database.

  5. VORTEX_PROVISION_POST_OPERATIONS_SKIP=1
    Skip configuration imports, database updates, and other post-provisioning steps. Essentially, this is drush sql:drop and $(drush sql:connect) < .data/db.sql commands. This is useful when you want to provision a site without running any additional operations.
    ahoy import-db uses this flag to import DB and exit.

  6. VORTEX_PROVISION_USE_MAINTENANCE_MODE=1
    Enable maintenance mode right after the site is bootstrappable and disable it at the end. Useful when you want to prevent users from accessing the site while it is being provisioned.

  7. VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE=1
    Verify that active configuration was not changed by database updates. When enabled and config files are present, the provision will fail if drush updatedb modifies active configuration, preventing drush config:import from silently overwriting those changes.

  8. VORTEX_PROVISION_SANITIZE_DB_SKIP=1
    Disable database sanitization.
tip

These variables can be set in your .env file to apply them globally or set in your CI or hosting provider's specific environment based on your needs.

Maintenance mode

During the provisioning process, you may want to enable maintenance mode to prevent users from accessing the site while it is being updated.

To enable maintenance mode, set the VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 environment variable in your .env file to apply it globally or set it in your hosting provider's specific environment.

Database sanitization

The provision.sh script includes a step to sanitize the database after provisioning. This helps ensure that sensitive data — like real email addresses, passwords, and user information — is replaced with safe, generic values in non-production environments. It prevents issues like accidentally sending emails to real users or exposing private data during testing, making shared environments safer to work with.

warning

Sanitization takes place only after the database is imported, so anyone with access to the dump file can still see sensitive data.

If your database has highly sensitive data, consider sanitizing the database dump before it can be downloaded (sanitize on export). There are tools available for this purpose, such as Drush GDPR Dumper or MTK. These tools can be easily integrated into Vortex-based projects without changing the provisioning process.

By default, the database sanitization step is enabled by default on all environments except production. To disable database sanitization, set the VORTEX_PROVISION_SANITIZE_DB_SKIP=1 in the .env file or in your hosting provider's specific environment.

Customizing database sanitization

Place these variables in the .env file or in your hosting provider's specific environment to further customize the database sanitization:

  1. VORTEX_PROVISION_SANITIZE_DB_EMAIL=user_%uid@your-site-domain.example
    Replace all emails with a tokenized email string.

  2. VORTEX_PROVISION_SANITIZE_DB_PASSWORD=<random or exact>
    Replace passwords with a random or exact value.

  3. VORTEX_PROVISION_SANITIZE_DB_REPLACE_USERNAME_WITH_EMAIL=0
    Replace username with email. Useful to also sanitize user names.

  4. VORTEX_PROVISION_SANITIZE_DB_ADDITIONAL_FILE=./scripts/sanitize.sql
    Path to a file with custom sanitization SQL queries.

Running custom scripts

The provision.sh script can execute custom scripts after all provisioning steps. This feature allows you to automate additional tasks specific to your project, such as conditionally enabling modules or running migrations in a specific order.

To run custom scripts, create a new file in the scripts/custom directory with the provision- prefix and the .sh extension, and make it executable with chmod +x scripts/custom/provision-10-example.sh. The script will be automatically discovered and executed.

It is recommended to use a 2-digit suffix to control the order of execution: e.g., provision-10-example.sh, provision-20-another-example.sh.

Conditional execution

You may choose to only perform an action based on a specific environment (the value of $settings['environment'] is populated by the Drupal settings file):

environment="$(drush php:eval "print \Drupal\core\Site\Settings::get('environment');")"

if echo "${environment}" | grep -q -e dev -e stage -e ci -e local; then
echo "> Running custom script for dev, stage, ci, or local environment."
# Place your commands here.
else
echo "> Skipping custom script for ${environment} environment."
fi

You may also conditionally perform an action based on whether the database is freshly imported or not:

if [ "${VORTEX_PROVISION_OVERRIDE_DB:-0}" = "1" ]; then
echo "> Fresh database detected."
else
echo "> Existing database detected."
fi

Expand below to see a provision scaffold script that you can use as a starting point for your custom scripts:

Example of a custom provision script
#!/usr/bin/env bash
##
# Example of the custom per-project command that will run after website is installed.
#
# Clone this file and modify it to your needs or simply remove it.
#
# For ordering multiple commands, use a two-digit suffix for clarity and consistency.
# This approach ensures a clear sequence and avoids potential ordering issues.
#
# Example:
# - provision-10-example.sh
# - provision-20-example.sh
# - provision-30-example.sh
#
# shellcheck disable=SC2086

set -eu
[ "${VORTEX_DEBUG-}" = "1" ] && set -x

# ------------------------------------------------------------------------------

info() { printf " ==> %s\n" "${1}"; }
task() { printf " > %s\n" "${1}"; }
note() { printf " %s\n" "${1}"; }

drush() { ./vendor/bin/drush -y "$@"; }

info "Started example operations."

# 👇 Get the current environment from Drupal settings.
environment="$(drush php:eval "print \Drupal\core\Site\Settings::get('environment');")"
note "Environment: ${environment}"

# 👇 Perform operations based on the current environment.
if echo "${environment}" | grep -q -e dev -e stage -e ci -e local; then
note "Running example operations in non-production environment."

# 👇 Enable custom site modules and run its deployment hooks.
task "Installing custom site modules."
drush pm:install ys_base
drush pm:install ys_search
drush pm:install ys_demo

# 👇 Conditionally perform an action if this is a "fresh" database.
if [ "${VORTEX_PROVISION_OVERRIDE_DB:-0}" = "1" ]; then
note "Fresh database detected. Performing additional example operations."
else
note "Existing database detected. Performing additional example operations."
fi
else
note "Skipping example operations in production environment."
fi

info "Finished example operations."
Related Documentation

For information about different types of Drupal hooks used during deployment and updates.

➡️ See Update Hooks