Installation
This page is for the developer or tech lead who sets up a Drupal project on Vortex. It takes you from an empty directory to a project that builds, tests, and deploys in continuous integration. Follow the steps in order: each step builds only on what the steps before it produced.
To add Vortex to a site you already have, follow the existing project steps instead. To update a project that already runs Vortex, see Updating Vortex.
Before you begin
Make sure you have the following:
- PHP 8.3 or later, and
curl git,tar, andcomposeron yourPATH- Docker with Docker Compose, Ahoy, and a running Pygmy, to build the site on your machine
- A GitHub account for the project repository
- A user account on Acquia or Lagoon, if you host there
- A CircleCI account, if you use CircleCI
The installer checks for git, tar, and composer when it starts, and it
stops with a Missing required command error when one of them is missing.
Installing Vortex into a new project
1. Choose the names
Settle the project's names before you run the installer. The machine names end up in directory names, module names, and code across the whole project, so you'll type them constantly, and they're costly to change later. The installer asks for these names:
- Site name
- Site machine name
- Organization name
- Organization machine name
- Custom modules prefix
- Custom theme machine name
It asks for the custom theme machine name only when you keep the default Custom (next prompt) answer at the Theme prompt. The other answers are the Olivero, Claro, and Stark core themes, which need no name.
Keep the machine names short, quick to type, and distinct from each other. These patterns work for the 2 names you'll type most:
- Custom modules prefix - built from the first letters of the site name.
Use the first 2 letters of a single-word name (
Falconbecomesfa), or the first letter of each word of a multi-word name (Star Warsbecomessw). Your custom modules then read assw_base,sw_search, and so on. - Custom theme machine name - the whole site name, shortened as much as
possible and without underscores where possible (
Star Warsbecomesstarwars,Falconbecomesfalcon). This keeps the theme name and the module prefix from colliding while both stay short enough to type often.
The installer's suggestions don't always match these patterns. For a 1-word
site machine name, it suggests the first 4 letters as the prefix instead of
2. For the theme, it suggests the site machine name itself, such as
star_wars. Change either suggestion at the prompt when it doesn't match
the pattern you chose.
2. Install Vortex
In a new, empty directory for your project, run the installer:
curl -SsL https://www.vortextemplate.com/install > installer.php && php installer.php
Complete the installation in the installer:
- Press any key to start the prompts.
- Answer each prompt, using the names from step 1. To go back to the previous prompt, press Ctrl+U.
- Review the Installation summary that follows the last prompt.
- Confirm Proceed with installing Vortex?. The installer copies the files into the directory and shows Finished installing Vortex.
- Answer Run the site build now?. Yes builds the site on your
machine, which takes about 5 to 10 minutes and needs the local tools
from Before you begin. The installer shows
Site is ready when the build succeeds. No skips the build, and
you can run
ahoy buildlater.
To have an AI coding agent install Vortex instead, run the installer
with --agent-help. It prints the instructions that an agent follows for a
non-interactive, programmatic installation:
curl -SsL https://www.vortextemplate.com/install > installer.php && php installer.php --agent-help
The /install path serves the installer for the current major line, the
one this site documents at /docs. Each installer installs the latest
release of its own line, or the line's development branch when the line has
no release yet. To install a specific line, download the installer from
that line's path instead:
https://www.vortextemplate.com/v1/installfor the1.xlinehttps://www.vortextemplate.com/v2/installfor the2.xline
After installation, ahoy update-vortex keeps your project on its major
line. See Updating Vortex.
3. Commit the initial project structure
The installer has already initialized a Git repository in the directory. Commit the files it created:
git add .
git commit -m "Initial commit"
4. Create a GitHub repository and push
Put the project on GitHub:
- Create an empty repository on GitHub, without a README, license, or
.gitignorefile, so it holds no commits that conflict with yours. - Push the initial commit to it, with the commands GitHub shows for an existing repository. The repository's page then lists your files.
5. Create an SSH key for deployments
If you answered Other or None at the Hosting provider prompt, only the Code artifact and Lagoon webhook deployment types and the Lagoon environment database source use these keys. Without any of them, skip to the next step.
Your continuous integration pipeline connects to your hosting provider over SSH to deploy code. On Lagoon, it fetches the database over SSH too. On Acquia, it downloads database backups through the Acquia Cloud API instead, with the API key you create in the next step. Generate a key pair for the automation:
ssh-keygen -m PEM -t rsa -b 4096 -C "deployer+myproject@example.com" -f ~/.ssh/deployer_myproject -N ""
The command writes the private key to the path after -f and the public key
to the same path with .pub added, both without a passphrase. Swap the
example project name in the comment and the path for your own. Every
supported hosting and continuous integration provider accepts the
-m PEM -t rsa format.
You can also generate 2 separate key pairs: one with read access for database fetches and one with write access for deployments. That way, you can revoke each one on its own. Acquia needs only the deployment key. The following steps note where each key goes.
You register the public key (the .pub file) with your hosting provider in
the next step. The private key stays on your machine until the continuous
integration setup, and it never goes anywhere else.
6. Set up hosting
Each answer you selected at the installer's Deployment types prompt adds
its type to VORTEX_DEPLOY_TYPES in .env. The following table maps each
answer to its type, its setup page, and its line in the deploy log:
| Answer | Type | Setup page | Deploy log line |
|---|---|---|---|
| Code artifact | artifact | Artifact deployment | Finished artifact deployment. |
| Lagoon webhook | lagoon | Lagoon deployment | Finished Lagoon deployment. |
| Custom webhook | webhook | Webhook deployment | Finished webhook deployment. |
If you answered Other or None at the Hosting provider prompt, there's nothing to set up on a platform. Set your type's CI variables, listed on Artifact deployment or Webhook deployment, in your CI provider instead: as repository variables in GitHub Actions, or project environment variables in CircleCI.
The Hosting section explains how the site behaves on each platform. For Acquia or Lagoon, pick the tab for your hosting provider:
- Acquia
- Lagoon
Complete these steps for Acquia:
- Add the public key created in step 5 to your Acquia account, so the automation can push code artifacts to your application's Git repository. With separate keys, add the deployment key.
- Check
VORTEX_ACQUIA_APP_NAMEin your.envfile. The installer fills it with your Hosting project name answer, which defaults to the site machine name. - If your Acquia application name (machine name) differs, correct the value
in
.env, then commit and push the change. - Create an Acquia Cloud API token for the account that runs the automation, under Account → API tokens in the Acquia Cloud UI. The token gives you an API key and secret, and the pipeline downloads database backups with them. Keep both values at hand, along with your application's Git repository URL, for the continuous integration setup in the next step.
You don't need to set DRUPAL_HASH_SALT on Acquia. The platform's settings
file supplies a per-environment hash_salt, and Vortex includes that
file automatically (see
Acquia settings file).
Complete these steps for Lagoon:
- Add the public key created in step 5 to your Lagoon user, so the automation can fetch databases and trigger deployments. With separate keys, add both public keys.
- Check
LAGOON_PROJECTin your.envfile. The installer fills it with your Hosting project name answer, which defaults to the site machine name. - If your Lagoon project name differs, correct it in
.envand indrush/sites/lagoon.site.yml, then commit and push the change. - Set a unique, long, random
DRUPAL_HASH_SALTvariable on every Lagoon environment (dev, stage, production), because Lagoon doesn't supply one. Without it, Vortex derives the salt from the database host. When the host changes, so does the salt, and every outstanding one-time login and password-reset link silently stops working.
7. Set up continuous integration
Pick the tab for the continuous integration provider you chose in the installer. Both providers run the same workflow, and the Continuous integration section covers its structure, jobs, and caching. If you answered None at the Continuous Integration provider prompt, the project has no pipeline, so skip this step and the next one.
- GitHub Actions
- CircleCI
Complete these steps for GitHub Actions:
- Open your repository's Actions tab. It lists the
Database, Build, Test and Deployworkflow from.github/workflows/build-test-deploy.yml, which GitHub Actions runs without further setup. - Under Settings → Secrets and variables → Actions, add the private key
created in step 5 as the
VORTEX_DEPLOY_SSH_PRIVATE_KEYsecret, for deployments. With separate keys, use the deployment key. - On Lagoon, add the private key as the
VORTEX_FETCH_DB_SSH_PRIVATE_KEYsecret too, for database fetches. With separate keys, use the read-only key. Acquia fetches the database through the Acquia Cloud API, so it doesn't need this secret. - On Acquia, add the API key and secret from step 6
as the
VORTEX_ACQUIA_KEYandVORTEX_ACQUIA_SECRETrepository secrets. - On Acquia, add 2 variables under
Settings → Secrets and variables → Actions → Variables:
VORTEX_DEPLOY_ARTIFACT_GIT_REMOTEwith your application's Git repository URL, andVORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAILwith the email address for the deployment commits.
Lagoon needs nothing more: it fetches and deploys with the SSH keys from items 2 and 3.
Complete these steps for CircleCI:
- Log in to CircleCI.
- Add your repository as a project. CircleCI detects the
.circleci/config and builds every push from then on. - Under Project Settings → SSH Keys, add the private key created in step 5. With separate keys, add both private keys.
- Copy the fingerprint that CircleCI generates for each key you added.
- Set the fingerprints in the
aliaseslist at the top of.circleci/config.yml:db_ssh_fingerprintfor database fetches anddeploy_ssh_fingerprintfor deployments. With a single key, both take the same fingerprint. On Acquia, which fetches the database through the Cloud API, the database job loads that key without using it, so givedb_ssh_fingerprintthe deployment key's fingerprint as well. - Commit and push the change to
.circleci/config.yml. - On Acquia, add the API key and secret from step 6
under Project Settings → Environment Variables as
VORTEX_ACQUIA_KEYandVORTEX_ACQUIA_SECRET. - On Acquia, add
VORTEX_DEPLOY_ARTIFACT_GIT_REMOTEwith your application's Git repository URL andVORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAILwith the email address for the deployment commits on the same screen.
Lagoon needs nothing more: it fetches and deploys with the SSH keys from item 3.
8. Run your first build
Push to a branch your pipeline builds, such as main or develop, or open
a pull request against one of them. Your continuous integration provider
builds the codebase, runs the tests, and deploys according to your
configuration. If a required value is missing, the job fails with a
Missing required value for ... message that names the variable.
Confirm that the first build passed:
- In GitHub Actions, every job of the
Database, Build, Test and Deployrun for your push passes. - In CircleCI, every job of the
commitworkflow for your push passes. - On either provider, the log of the deploy job's Deploy step shows a
Finished artifact deployment.,Finished Lagoon deployment., orFinished webhook deployment.line for each type you chose at the installer's Deployment types prompt. The table in step 6 maps each answer to its line.
Installing Vortex into an existing project
The installer can't predict what state your project is in, so you install Vortex into a clean working copy and then merge your existing project back into it.
In step 3, you delete every file in the working copy except the .git
directory. Back up your project before you start.
1. Choose the names
Settle the project's names before you run the installer. The machine names end up in directory names, module names, and code across the whole project, so you'll type them constantly, and they're costly to change later. The installer asks for these names:
- Site name
- Site machine name
- Organization name
- Organization machine name
- Custom modules prefix
- Custom theme machine name
It asks for the custom theme machine name only when you keep the default Custom (next prompt) answer at the Theme prompt. The other answers are the Olivero, Claro, and Stark core themes, which need no name.
Keep the machine names short, quick to type, and distinct from each other. These patterns work for the 2 names you'll type most:
- Custom modules prefix - built from the first letters of the site name.
Use the first 2 letters of a single-word name (
Falconbecomesfa), or the first letter of each word of a multi-word name (Star Warsbecomessw). Your custom modules then read assw_base,sw_search, and so on. - Custom theme machine name - the whole site name, shortened as much as
possible and without underscores where possible (
Star Warsbecomesstarwars,Falconbecomesfalcon). This keeps the theme name and the module prefix from colliding while both stay short enough to type often.
The installer's suggestions don't always match these patterns. For a 1-word
site machine name, it suggests the first 4 letters as the prefix instead of
2. For the theme, it suggests the site machine name itself, such as
star_wars. Change either suggestion at the prompt when it doesn't match
the pattern you chose.
2. Copy your project aside
Copy all files from your existing project, hidden files included, into a temporary directory outside the project.
3. Clean the working copy
In your existing project, prepare an empty branch:
- Create a new branch.
- Remove all files except the
.gitdirectory.
4. Install Vortex
Run the installer in the cleaned working copy:
curl -SsL https://www.vortextemplate.com/install > installer.php && php installer.php
Answer the prompts as in step 2 of the new project steps. When the installer asks Run the site build now?, answer No, because your own code isn't back in place yet.
5. Commit the installed structure
Commit the files the installer created:
git add .
git commit -m "Initial Vortex commit"
6. Merge your project back
Bring your own code back on top of the installed structure:
- Copy your files back from the temporary directory over the installed ones.
- Review the diff and keep changes selectively.
- Merge
composer.jsonby hand so every Vortex entry survives, including thedrevops/vortex-toolingrequirement that provides the scripts. - Regenerate
composer.lockwithcomposer update, and review the changes it makes. - Run
composer validateto check the result. It reports./composer.json is validwhen the file passes.
7. Commit and push
Save the merged project to your repository:
- Commit the result to the branch.
- Push the branch to the remote repository.
8. Create an SSH key for deployments
If you answered Other or None at the Hosting provider prompt, only the Code artifact and Lagoon webhook deployment types and the Lagoon environment database source use these keys. Without any of them, skip to the next step.
Your continuous integration pipeline connects to your hosting provider over SSH to deploy code. On Lagoon, it fetches the database over SSH too. On Acquia, it downloads database backups through the Acquia Cloud API instead, with the API key you create in the next step. Generate a key pair for the automation:
ssh-keygen -m PEM -t rsa -b 4096 -C "deployer+myproject@example.com" -f ~/.ssh/deployer_myproject -N ""
The command writes the private key to the path after -f and the public key
to the same path with .pub added, both without a passphrase. Swap the
example project name in the comment and the path for your own. Every
supported hosting and continuous integration provider accepts the
-m PEM -t rsa format.
You can also generate 2 separate key pairs: one with read access for database fetches and one with write access for deployments. That way, you can revoke each one on its own. Acquia needs only the deployment key. The following steps note where each key goes.
You register the public key (the .pub file) with your hosting provider in
the next step. The private key stays on your machine until the continuous
integration setup, and it never goes anywhere else.
9. Set up hosting
Each answer you selected at the installer's Deployment types prompt adds
its type to VORTEX_DEPLOY_TYPES in .env. The following table maps each
answer to its type, its setup page, and its line in the deploy log:
| Answer | Type | Setup page | Deploy log line |
|---|---|---|---|
| Code artifact | artifact | Artifact deployment | Finished artifact deployment. |
| Lagoon webhook | lagoon | Lagoon deployment | Finished Lagoon deployment. |
| Custom webhook | webhook | Webhook deployment | Finished webhook deployment. |
If you answered Other or None at the Hosting provider prompt, there's nothing to set up on a platform. Set your type's CI variables, listed on Artifact deployment or Webhook deployment, in your CI provider instead: as repository variables in GitHub Actions, or project environment variables in CircleCI.
The Hosting section explains how the site behaves on each platform. For Acquia or Lagoon, pick the tab for your hosting provider:
- Acquia
- Lagoon
Complete these steps for Acquia:
- Add the public key created in step 8 to your Acquia account, so the automation can push code artifacts to your application's Git repository. With separate keys, add the deployment key.
- Check
VORTEX_ACQUIA_APP_NAMEin your.envfile. The installer fills it with your Hosting project name answer, which defaults to the site machine name. - If your Acquia application name (machine name) differs, correct the value
in
.env, then commit and push the change. - Create an Acquia Cloud API token for the account that runs the automation, under Account → API tokens in the Acquia Cloud UI. The token gives you an API key and secret, and the pipeline downloads database backups with them. Keep both values at hand, along with your application's Git repository URL, for the continuous integration setup in the next step.
You don't need to set DRUPAL_HASH_SALT on Acquia. The platform's settings
file supplies a per-environment hash_salt, and Vortex includes that
file automatically (see
Acquia settings file).
Complete these steps for Lagoon:
- Add the public key created in step 8 to your Lagoon user, so the automation can fetch databases and trigger deployments. With separate keys, add both public keys.
- Check
LAGOON_PROJECTin your.envfile. The installer fills it with your Hosting project name answer, which defaults to the site machine name. - If your Lagoon project name differs, correct it in
.envand indrush/sites/lagoon.site.yml, then commit and push the change. - Set a unique, long, random
DRUPAL_HASH_SALTvariable on every Lagoon environment (dev, stage, production), because Lagoon doesn't supply one. Without it, Vortex derives the salt from the database host. When the host changes, so does the salt, and every outstanding one-time login and password-reset link silently stops working.
10. Set up continuous integration
Pick the tab for the continuous integration provider you chose in the installer. Both providers run the same workflow, and the Continuous integration section covers its structure, jobs, and caching. If you answered None at the Continuous Integration provider prompt, the project has no pipeline, so skip this step and the next one.
- GitHub Actions
- CircleCI
Complete these steps for GitHub Actions:
- Open your repository's Actions tab. It lists the
Database, Build, Test and Deployworkflow from.github/workflows/build-test-deploy.yml, which GitHub Actions runs without further setup. - Under Settings → Secrets and variables → Actions, add the private key
created in step 8 as the
VORTEX_DEPLOY_SSH_PRIVATE_KEYsecret, for deployments. With separate keys, use the deployment key. - On Lagoon, add the private key as the
VORTEX_FETCH_DB_SSH_PRIVATE_KEYsecret too, for database fetches. With separate keys, use the read-only key. Acquia fetches the database through the Acquia Cloud API, so it doesn't need this secret. - On Acquia, add the API key and secret from step 9
as the
VORTEX_ACQUIA_KEYandVORTEX_ACQUIA_SECRETrepository secrets. - On Acquia, add 2 variables under
Settings → Secrets and variables → Actions → Variables:
VORTEX_DEPLOY_ARTIFACT_GIT_REMOTEwith your application's Git repository URL, andVORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAILwith the email address for the deployment commits.
Lagoon needs nothing more: it fetches and deploys with the SSH keys from items 2 and 3.
Complete these steps for CircleCI:
- Log in to CircleCI.
- Add your repository as a project. CircleCI detects the
.circleci/config and builds every push from then on. - Under Project Settings → SSH Keys, add the private key created in step 8. With separate keys, add both private keys.
- Copy the fingerprint that CircleCI generates for each key you added.
- Set the fingerprints in the
aliaseslist at the top of.circleci/config.yml:db_ssh_fingerprintfor database fetches anddeploy_ssh_fingerprintfor deployments. With a single key, both take the same fingerprint. On Acquia, which fetches the database through the Cloud API, the database job loads that key without using it, so givedb_ssh_fingerprintthe deployment key's fingerprint as well. - Commit and push the change to
.circleci/config.yml. - On Acquia, add the API key and secret from step 9
under Project Settings → Environment Variables as
VORTEX_ACQUIA_KEYandVORTEX_ACQUIA_SECRET. - On Acquia, add
VORTEX_DEPLOY_ARTIFACT_GIT_REMOTEwith your application's Git repository URL andVORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAILwith the email address for the deployment commits on the same screen.
Lagoon needs nothing more: it fetches and deploys with the SSH keys from item 3.
11. Run your first build
Push to a branch your pipeline builds, such as main or develop, or open
a pull request against one of them. Your continuous integration provider
builds the codebase, runs the tests, and deploys according to your
configuration. If a required value is missing, the job fails with a
Missing required value for ... message that names the variable.
Confirm that the first build passed:
- In GitHub Actions, every job of the
Database, Build, Test and Deployrun for your push passes. - In CircleCI, every job of the
commitworkflow for your push passes. - On either provider, the log of the deploy job's Deploy step shows a
Finished artifact deployment.,Finished Lagoon deployment., orFinished webhook deployment.line for each type you chose at the installer's Deployment types prompt. The table in step 9 maps each answer to its line.
Updating Vortex
After your project is running, Updating Vortex explains how to bring in each new Vortex release.
What's next
- Development - the day-to-day commands for working on the project
- Continuous integration - the pipeline's jobs, caching, and maintenance tasks
- Deployment - the deployment types and notifications
- Hosting - how the site behaves on Acquia and Lagoon