(*this post focuses on the usecase of using drush within a DDEV hosted docker container, i.e. running ddev drush ... command, if you are using globally installed drush a portion of this post may not apply to you.)

Preliminary Setup

Part-1: Setup SSH Public Key Authentication

  1. generate ssh key pair cd ~/.ssh && ssh-keygen -t rsa -f ~/.ssh/id_rsa_example, copy content in ~/.ssh/id_rsa_example.pub file for later

  2. add to target server: ssh example.com.au then cd ~/.ssh && vi authorised_keys, then paste the copied content from file ~/.ssh/id_rsa_example.pub in previous step

  3. trial ssh key connection via ddev ssh then ssh example@example.com.au -i ~/.ssh/id_rsa_example (add -p port-number if applies to you)

Part-2: Setup $PROJECT/drush/sites/self.site.yml File

  1. create emptu self.site.yml file under $PROJECT/drush/sites directory

  2. for each alias (development / stage / production) add an alias item in the self.site.yml file, for instance:

    1
    2
    3
    4
    5
    6
    7
    
    + live:
    +   host: opc.com.au
    +   user: opcit
    +   root: /home/example/public_html/web
    +   uri: http://example.com.au
    +   ssh:
    +     options: "-p 2222 -i ~/.ssh/id_rsa_example"
    

    Note for parameters:

    • host : The fully-qualified domain name of the remote system hosting the Drupal instance.
    • user : The username to log in as when using ssh or docker. If you don’t declare it here, you can declare it in the ~/.ssh/config file in DDEV container (NOT in your host machine !!!!)
    • uri: The value of –uri should always be the same as when the site is being accessed from a web browser
    • ssh: Additional SSH options, here I’ve specified the flag and manually used certain private key for authentication

Part-3: Trial via drush @alias-name status Command

  1. Run drush @alias-name status command, you should get something like the following:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    Drupal version   : 10.6.1                                               
    Site URI         : http://example.com.au                                    
    DB driver        : mysql                                                
    DB hostname      : localhost                                            
    DB port          : 3306                                                 
    DB username      : example_drupal                                         
    DB name          : example_drupal                                         
    Database         : Connected                                            
    Drupal bootstrap : Successful                                           
    Default theme    : example_theme                                                
    Admin theme      : gin                                                  
    PHP binary       : /opt/alt/php81/usr/bin/php                           
    PHP config       : /opt/alt/php81/etc/php.ini                           
    PHP OS           : Linux                                                
    PHP version      : 8.1.33                                               
    Drush script     : /home/example/public_html/vendor/bin/drush             
    Drush version    : 12.5.3.0                                             
    Drush temp       : /tmp                                                 
    Drush configs    : /home/example/public_html/vendor/drush/drush/drush.yml 
    Install profile  : standard                                             
    Drupal root      : /home/example/public_html       
    Site path        : sites/default                                        
    Files, Public    : sites/default/files                                  
    Files, Private   : sites/default/files/private                          
    Files, Temp      : sites/default/files/private/tmp                      
    Connection to example.com.au closed.
    
  2. If you are encountering error, please refer to the “Common Issue” section for resolution for various error.

Common Usage

PENDING !!!!!


Common Issue

Issue-1: SSH Authentication Issue when running ddev drush site-aliases

During my trial experiment, I get held back for a long time because the SSH key authentication kept failing, claiming the private key I provided via -i ~/.ssh/id_rsa_cpanel is not found (since I am using SSH public key to establish the connection)

1
2
3
4
5
6
7
>  ddev drush @live status --debug
    [preflight] Config paths: /var/www/html/vendor/drush/drush/drush.yml
    ...
    [debug] Redispatch hook status [0.42 sec, 3.15 MB]
    [info] Executing: ssh -t -p 2222 -i ~/.ssh/id_rsa example@example.com.au '/home/example/public_html/vendor/bin/drush status -vvv --uri=http://example.com.au' [0.43 sec, 3.29 MB]
   Warning: Identity file /home/user_name/.ssh/id_rsa_cpanel not accessible: No such file or directory.
   example@example.com.au's password: ...

I soon realised that since I am using ddev to run the drush command, it only have access to the files inside its own container (it has no access to the SSH keys in its host machine), hence in order for it to work, I need to generate a new pair and add it to the authorised_keys file in the target server:

  1. generate ssh key pair cd ~/.ssh && ssh-keygen -t rsa -f ~/.ssh/id_rsa_example, copy content in ~/.ssh/id_rsa_example.pub file for later

  2. add to target server: ssh example.com.au then cd ~/.ssh && vi authorised_keys, then paste the copied content from file ~/.ssh/id_rsa_example.pub in step-1

  3. finally edit your self.site.yml file:

    1
    2
    3
    4
    5
    6
    7
    8
    
    live:
      host: example.com.au
      user: example
      root: /home/example/public_html/web
      uri: http://example.com.au
      ssh:
    -   options: "-p 2222 -i /path/to/ssh-key-in-host-machine" <-- unreachable from docker POV 
    +   options: "-p 2222 -i ~/.ssh/id_rsa_example"
    

(*I believe, alternatively, you can also copy the one in your host machine over)

Issue-2: No such file or directory (Cannot find drush)

On my trial, the drush site:alias seems to keep ignoring my last bit of the path in root attribute, for instance when I set root:/home/example/public_html, it seems to always run ssh -t example@example.com.au '/home/example/vendor/bin/drush status --uri=http://example.com.au instead:

1
2
3
4
5
6
7
>  ddev drush @live status --debug
     [preflight] Config paths: /var/www/html/vendor/drush/drush/drush.yml
     ...
     [debug] Redispatch hook status [0.27 sec, 3.15 MB]
     [info] Executing: ssh -t -p 2222 -i ~/.ssh/id_rsa_cpanel example@example.com.au '/home/example/vendor/bin/drush status -vvv --uri=http://example.com.au' [0.28 sec, 3.29 MB]
   bash: /home/exampleit/vendor/bin/drush: No such file or directory
   Connection to example.com.au closed.

After some digging it is found that Drupal by default assumes your website to live inside a web folder and will escape from that folder level that contains the vendor/bin/drush file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# FILE: src/Drupa Finder/DrushDrupalFinder.php
<?php
public function getDrupalRoot()
{
    $core = InstalledVersions::getInstallPath('drupal/core');
    return $core ? Path::canonicalize(realpath(dirname($core))) : false;
    # ↑
    # dirname($core)       - Truncates/removes the last path segment (core), leaving the parent directory (e.g., /path/to/drupal/web)
    # realpath()           - Resolves any symlinks and relative paths to get the absolute path
    # Path::canonicalize() - Normalizes the path format for the current OS
}

To accommodate this, no matter the website lives inside the web folder or not, always put trailing web in your root file path :

1
2
3
4
5
6
7
8
live:
  host: example.com.au
  user: example
- root: /home/example/public_html
+ root: /home/example/public_html/web
  uri: http://example.com.au
  ssh:
    options: "-p 2222 -i ~/.ssh/id_rsa_example"

(via running drush @live status and you can find the actual website root path:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Drupal version   : 10.6.1                                               
Site URI         : http://example.com.au                                    
DB driver        : mysql                                                
DB hostname      : localhost                                            
DB port          : 3306                                                 
DB username      : example_drupal                                         
DB name          : example_drupal                                         
Database         : Connected                                            
Drupal bootstrap : Successful                                           
Default theme    : example_theme                                                
Admin theme      : gin                                                  
PHP binary       : /opt/alt/php81/usr/bin/php                           
PHP config       : /opt/alt/php81/etc/php.ini                           
PHP OS           : Linux                                                
PHP version      : 8.1.33                                               
Drush script     : /home/example/public_html/vendor/bin/drush             
Drush version    : 12.5.3.0                                             
Drush temp       : /tmp                                                 
Drush configs    : /home/example/public_html/vendor/drush/drush/drush.yml 
Install profile  : standard                                             
Drupal root      : /home/example/public_html        <-------[HERE]                           
Site path        : sites/default                                        
Files, Public    : sites/default/files                                  
Files, Private   : sites/default/files/private                          
Files, Temp      : sites/default/files/private/tmp                      
Connection to example.com.au closed.

Reference

  • Drush Documentation - site:aliases: link

  • Drush Documentation - site:ssh: link

  • Drush Documentation - sql:sync: link

    • so you can synchronise local/stage/production databases via drush sql:sync @source @target
    • (equivalent to running drush sql-dump @source | drush @target sql-cli)
  • Drush Documentation - core:rsync: link

    • so you can synchronise local/stage/production files via drush rsync @source @target