Skip to main content

Development

Typical development process

  1. Pull the latest changes from the remote repository.
  2. Fetch the latest database dump from the production environment.
  3. Build the project.
  4. Start a new feature or bugfix branch:
    • Create a new branch from develop.
    • Implement the feature or fix the bug.
  5. Run tests:
    • Run automated tests locally.
    • Fix any failing tests.
  6. Run code quality checks:
    • Run static code analysis locally.
    • Fix any issues reported.
  7. Commit changes to the branch and push it to the remote repository.
  8. Create a pull request:
    • Create a pull request from the branch to develop.
    • Assign reviewers.
    • Wait for the continuous integration pipeline to pass.

Common commands

The most common day-to-day commands. Each video is a live recording captured on a fresh Vortex project.

Build the project

ahoy build rebuilds the whole stack from scratch: it recreates the containers, installs the Composer and front-end dependencies, compiles the theme assets, and provisions the site from the database dump.

Re-provision the site

ahoy provision re-imports the database dump from .data/db.sql into the running stack and applies the provisioning steps: database updates, configuration import, cache rebuilds and deploy hooks.

Run linters

ahoy lint runs all the code quality checks: back-end (PHPCS, PHPStan, Rector), front-end (Twig CS Fixer, ESLint, Stylelint) and test linting (Gherkin Lint).

Run unit, kernel and functional tests

ahoy test runs all the PHPUnit test suites: unit, kernel, functional and functional JavaScript.

Run BDD tests

ahoy test-bdd runs the Behat tests against the provisioned site, driving a real browser inside the container stack.

Running CLI commands

You can run CLI commands inside the project containers.

# Run a command in the CLI container
ahoy cli echo "Hello, World!"
# SSH into the CLI container
ahoy cli

You can also use shortcuts for common commands:

# Run Drush command
ahoy drush status
# Run Composer command
ahoy composer install

Switching branches

When switching to a new branch, there is no need to rebuild the entire project as it may take a long time. Instead, you can run these commands as needed based on what changed:

# Update Composer dependencies (only if composer.json/composer.lock changed)
ahoy composer install
# Rebuild frontend assets (only if theme files changed)
ahoy fe
# Provision site (only if database or configuration changes expected)
ahoy provision

Resetting the codebase

To reset the local environment, use the reset command. This will stop and remove all containers and downloaded dependency packages (vendor, node_modules etc.).

# Reset local environment
ahoy reset
# Fully reset repository to a state as if it was just cloned
ahoy reset --hard

Environment variables

To update environment variables in your local development environment:

  1. Edit variables in .env.local file
  2. Apply changes by re-creating the containers (a plain restart does not re-read the .env files):
ahoy up

➡️ See Variables for the full variable reference.

Common issues and solutions

Site not loading

ahoy doctor # Check for common issues
ahoy down && ahoy up # Restart containers
ahoy info # Verify URLs and ports

Database connection errors

docker compose ps # Check if the database container is running
ahoy reset # Last resort: rebuild everything

Permission issues

# Fix file permissions (Linux/Mac)
sudo chown -R $USER:$USER .

Reading logs

# Show container logs
ahoy logs
# Check recent logs of a single container
ahoy logs -- --tail=50 cli
# View Drupal watchdog logs
ahoy drush watchdog:show --count=20

Beyond local development

Expand to see the complete code lifecycle
Local Development
═════════════════════════════════════════════════════════════════════════════════════════
Developer writes code ──► Build and test locally ──► Commit changes


Git Repository
═════════════════════════════════════════════════════════════════════════════════════════
Push to remote branch ──► Open/Update Pull Request


┌─ CI Pipeline ────────────────────────────────────────────────────────────────────────────┐
│ │
│ ┌─ Database Job (Nightly) ───────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Scheduled ──► Download production ──► Sanitize database ──► Store database cache │ │
│ │ trigger database Remove sensitive data │ │
│ │ │ │
│ └─────────────────────────────────────┬──────────────────────────────────────────────┘ │
│ │ Provides cached database │
│ ▼ │
│ ┌─ Lint Job ────────────┐ ┌─ Database Job ────────────────┐ ┌─ Audit Job ──────────┐ │
│ │ │ │ ◆ Nightly cache exists? │ │ Composer audit │ │
│ │ Build CLI container │ │ Yes ──► job succeeds │ │ (advisories) │ │
│ │ ▼ │ │ No ──► download, sanitize, │ │ ▼ │ │
│ │ Composer validate │ │ store cache │ │ Gitleaks │ │
│ │ ▼ │ └───────────────┬───────────────┘ │ (committed secrets) │ │
│ │ Composer normalize │ ▼ │ │ │
│ │ ▼ │ ┌─ Build Job ───────────────────┐ │ │ │
│ │ Hadolint │ │ Code assembly │ │ │ │
│ │ ▼ │ │ Docker, Composer deps, │ │ │ │
│ │ DCLint │ │ NPM deps, assets │ │ │ │
│ │ ▼ │ │ ▼ │ │ │ │
│ │ PHPCS │ │ Website setup │ │ │ │
│ │ ▼ │ │ Import cached DB, drush │ │ │ │
│ │ PHPStan │ │ deploy, custom scripts │ │ │ │
│ │ ▼ │ │ ▼ │ │ │ │
│ │ Rector │ │ Testing │ │ │ │
│ │ ▼ │ │ PHPUnit tests ──► Behat tests │ │ │ │
│ │ Twig CS Fixer │ └───────────────┬───────────────┘ │ │ │
│ │ ▼ │ │ │ │ │
│ │ Gherkin Lint │ │ │ │ │
│ │ ▼ │ │ │ │ │
│ │ ESLint / Stylelint │ │ │ │ │
│ │ │ │ │ │ │
│ └──────────┬────────────┘ │ │ │ │
│ │ │ │ │ │
│ ▼ ▼ │ │ │
│ ┌─ Deployment Job ─────────────────────────────────────────┐ │ │ │
│ │ │ │ │ │
│ │ Webhook Artifact Lagoon │ │ Does not gate │ │
│ │ Call URL Package artifact Run Lagoon CLI deploy │ │ deployment │ │
│ │ │ │ │ │
│ └──────────────────────────────────────────────────────────┘ └──────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────┘


Hosting Platform
═════════════════════════════════════════════════════════════════════════════════════════
◆ Environment ──No──► Sync DB from production ───┐
exists? │
│ Yes ▼
└──────────────────────────────────► drush deploy ──► Custom scripts ──► Notifications


Available Environments
═════════════════════════════════════════════════════════════════════════════════════════
┊ PR Environment ┊ Dev Staging Production
┊ (auto-removed) ┊ develop branch main branch production branch or tag

See also

TopicDescription
DatabaseFetching, refreshing, and exporting databases
ComposerManaging packages, patching, security auditing
DebuggingXdebug, curl testing, container access
PHPUnitUnit, kernel, and functional testing
BehatBehavior-driven (BDD) testing
JestJavaScript unit testing
Visual regressionDiffy-powered visual regression on deployments
AIThe AI agent configuration files
FAQsAnswers to common operational questions
VariablesThe full environment variable reference