
Drush alias can be a powerful tool for managing multiple Drupal installations, but it can also lead to issues when configurations conflict between different projects if it isn't configured correctly. I faced a frustrating problem where every Drush installation would read the first drush.yml
configuration file it encountered, causing conflicts across projects that live in different directories. With Drush documentation being scattered, it took some time to diagnose the issue. In this guide, I’ll explain how I resolved this Drush configuration problem and provide the best practices for configuring Drush aliases as well as alternative methods for multiple Drupal projects that live in different directories.
My Setup
I am currently working on three different Drupal projects:
- Drupal 10.3 ~/Sites/drupal
- Drupal 10.4 ~/Sites/project1
- Drupal 11 ~/Sites/cms
Each project has unique data, modules, and requirements. Instead of using Docker or other containers, I rely on Herd and DBngin running on MacOS to serve data from my local environment. While each Drupal installation runs Drush 13+, they all require separate configurations to ensure proper database access, directory and URL handling.
Using the Drush alias method.
1. Per-Site Alias (Only for One Drupal Project)
Option 1: Use self.site.yml
(Recommended)
Path:DRUPAL_ROOT/drush/sites/self.site.yml
- Purpose: Defines the alias for the current site only (Drush will automatically use this alias when running commands inside the project directory).
- Recommended for sites that do not need remote aliases.
Example:
Now, you can use:
drush @self status
Option 2: Use sitename.site.yml
Path:DRUPAL_ROOT/drush/sites/sitename.site.yml
- Purpose: Defines a named alias (
@sitename
) for this project. - Useful if you want to use a custom alias names.
Example:
Now, you can use:
2. Global Alias (Available for All Drupal Projects)
If you want the alias to be available for all projects on your system, use one of these global locations:
Option 1: User-Specific Drush Aliases
Path:~/.drush/drush.yml
- Purpose: Available for all Drupal projects on this user’s system.
Alternative Path (for structured site aliases):~/.drush/sites/self.site.yml
- Purpose: If you want to follow the per-site structure but store it globally.
Example: ~/.drush/drush.yml
- Now, you can use:
drush @myproject status
ordrush @staging sql-dump
3. System-Wide Drush Alias
Path:/etc/drush/drush.yml
- Purpose: Available to all users on the system.
- Requires root access to modify.
- Ideal for shared hosting environments.
Example: /etc/drush/drush.yml
All users on the system can now run:
How to Verify an Alias
After adding an alias file, check if Drush recognises it:
This should list all available aliases, including your new one.
To test an alias, run:
Summary Table
Alias Scope | File Path | Purpose |
---|---|---|
Per-Site Alias (Auto-Detect) | DRUPAL_ROOT/drush/sites/self.site.yml | Automatically used inside this project |
Per-Site Named Alias | DRUPAL_ROOT/drush/sites/sitename.site.yml | Only available inside this project |
User-Specific Alias | ~/.drush/drush.yml | Available for all projects for this user |
User-Specific Site Alias | ~/.drush/sites/self.site.yml | Site-specific alias, but stored globally |
System-Wide Alias | /etc/drush/drush.yml | Available for all users on the system |
Best Practices
- For local development → Use
self.site.yml
inside the project. - For multiple environments (e.g., staging, production) → Use global aliases in
~/.drush/drush.yml
. - For shared hosting → Use
/etc/drush/drush.yml
.
Using the .bashrc or .zshrc method.
I discovered the .bashrc/.zshrc method that accomplishes the outcome that I required. The code uses commands available on all *nix systems so it is very easy to implement.
You place this code into your .bashrc or .zshrc file depending on your shell type.
# Function to update vendor/bin path dynamically only inside ~/Sites
function update_vendor_bin_path() {
if [[ "$PWD" == $HOME/Sites* ]]; then
if [ -d "$PWD/vendor/bin" ]; then
# Remove only the previous vendor/bin path from PATH
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v "$HOME/Sites/.*/vendor/bin" | tr '\n' ':')
export PATH="$PWD/vendor/bin:$PATH"
fi
fi
}
# Hook into 'cd' command to update vendor/bin path automatically
autoload -U add-zsh-hook
add-zsh-hook chpwd update_vendor_bin_path
# Run on startup so it works immediately inside ~/Sites
update_vendor_bin_path
Now, when you switch into any directory inside of ~./Sites the appropriate vendor/bin will be added to your $PATH.