github.com/ddev/ddev@v1.23.2-0.20240519125000-d824ffe36ff3/docs/content/users/extend/custom-commands.md (about) 1 --- 2 search: 3 boost: 2 4 --- 5 # Custom Commands 6 7 Custom commands can easily be added to DDEV, to be executed on the host or in containers. 8 9 This involves adding a Bash script to the project in `.ddev/commands/host`, a specific container in `.ddev/commands/<containername>`, or globally in `~/.ddev/commands`. 10 11 Example commands in `ddev/commands/*/*.example` can be copied, moved, or symlinked. 12 13 For example, [.ddev/commands/host/mysqlworkbench.example](https://github.com/ddev/ddev/blob/master/pkg/ddevapp/global_dotddev_assets/commands/host/mysqlworkbench.example) can be used to add a `ddev mysqlworkbench` command. Rename it from `mysqlworkbench.example` to `mysqlworkbench`. If you’re on macOS or Linux (or some configurations of Windows) you can `cd .ddev/commands/host && ln -s mysqlworkbench.example mysqlworkbench`. 14 15 The [`ddev mysql`](../usage/commands.md#mysql) runs the `mysql` client inside the `db` container command using this technique. See the [`ddev mysql` command](https://github.com/ddev/ddev/blob/master/pkg/ddevapp/global_dotddev_assets/commands/db/mysql). 16 17 ## Notes for All Command Types 18 19 * The command filename is not what determines the name of the command. That comes from the “Usage” doc line (`## Usage: commandname`). 20 * To confirm that your custom command is available, run `ddev -h` and look for it in the list. 21 22 ## Host Commands 23 24 To provide host commands, place a Bash script in `.ddev/commands/host`. For example, a PhpStorm launcher to make the `ddev phpstorm` command might go in `.ddev/commands/host/phpstorm` with these contents. The `OSTypes` and `HostBinaryExists` annotations are optional, but are useful to prevent the command from showing up if it's not useful to the user. 25 26 ```bash 27 #!/usr/bin/env bash 28 29 ## Description: Open PhpStorm with the current project 30 ## Usage: phpstorm 31 ## Example: "ddev phpstorm" 32 ## OSTypes: darwin 33 ## HostBinaryExists: "/Applications/PhpStorm.app" 34 35 # Example is macOS-specific, but easy to adapt to any OS 36 open -a PhpStorm.app ${DDEV_APPROOT} 37 ``` 38 39 ## Container Commands 40 41 To provide a command which will execute in a container, add a Bash script to `.ddev/commands/<container_name>`, for example, `.ddev/commands/web/mycommand`. The Bash script will be executed inside the named container. For example, see the [several standard DDEV script-based web container commands](https://github.com/ddev/ddev/blob/master/pkg/ddevapp/global_dotddev_assets/commands/web). 42 43 You can run commands in custom containers as well as standard DDEV `web` and `db` containers. Use the service name, like `.ddev/commands/solr/<command>`. The only catch with a custom container is that your service must mount `/mnt/ddev-global-cache` like the `web` and `db` containers do; the `volumes` section of `docker-compose.<servicename>.yaml` needs: 44 45 ``` 46 volumes: 47 - ddev-global-cache:/mnt/ddev-global-cache 48 ``` 49 50 For example, to add a `solrtail` command that runs in a Solr service, add `.ddev/commands/solr/solrtail` with: 51 52 ```bash 53 #!/bin/bash 54 55 ## Description: Tail the main solr log 56 ## Usage: solrtail 57 ## Example: ddev solrtail 58 59 tail -f /opt/solr/server/logs/solr.log 60 ``` 61 62 ## Global Commands 63 64 Global commands work exactly the same as project-level commands, but they need to go in your *global* `.ddev` directory. Your home directory has a `.ddev/commands` in it, where you can add host, web, or db commands. 65 66 Changes to the command files in the global `.ddev` directory need a `ddev start` for changes to be picked up by a project, as the global commands are copied to the project on start. 67 68 ## Shell Command Examples 69 70 There are many examples of [global](https://github.com/ddev/ddev/tree/master/pkg/ddevapp/global_dotddev_assets/commands) and [project-level](https://github.com/ddev/ddev/tree/master/pkg/ddevapp/dotddev_assets/commands) custom/shell commands that ship with DDEV you can adapt for your own use. They can be found in your `~/.ddev/commands/*` directories and in your project’s `.ddev/commands/*` directories. There you’ll see how to provide usage, examples, and how to use arguments provided to the commands. For example, the [`xdebug` command](https://github.com/ddev/ddev/blob/master/pkg/ddevapp/global_dotddev_assets/commands/web/xdebug) shows simple argument processing and the [launch command](https://github.com/ddev/ddev/blob/master/pkg/ddevapp/global_dotddev_assets/commands/host/launch) demonstrates flag processing. 71 72 ## Command Line Completion 73 74 If your custom command has a set of pre-determined valid arguments it can accept, you can use the [`AutocompleteTerms`](#autocompleteterms-annotation). 75 76 For dynamic completion, you can create a separate script with the same name in a directory named `autocomplete`. 77 For example, if your command is in `~/.ddev/commands/web/my-command`, your autocompletion script will be in `~/.ddev/commands/web/autocomplete/my-command`. 78 79 When you press tab on the command line after your command, the associated autocomplete script will be executed. The current command line (starting with the name of your command) will be passed into the completion script as arguments. If there is a space at the end of the command line, an empty argument will be included. 80 81 For example: 82 83 * `ddev my-command <tab>` will pass `my-command` and an empty argument into the autocomplete script. 84 * `ddev my-command som<tab>` will pass `my-command`, and `som` into the autocomplete script. 85 86 The autocomplete script should echo the valid arguments as a string separated by line breaks. You don't need to filter the arguments by the last argument string (e.g. if the last argument is `som`, you don't need to filter out any arguments that don't start with `som`). That will be handled for you before the result is given to your shell as completion suggestions. 87 88 The web container's [`nvm` autocomplete script](https://github.com/ddev/ddev/blob/master/pkg/ddevapp/global_dotddev_assets/commands/web/autocomplete/nvm) shows how this can be used to forward completion requests to a relevant script in the container. 89 90 ## Environment Variables Provided 91 92 A number of environment variables are provided to these command scripts. These are generally supported, but please avoid using undocumented environment variables. Useful variables for host scripts are: 93 94 * `DDEV_APPROOT`: File system location of the project on the host 95 * `DDEV_DATABASE`: Database in use, in format `type:version` (example: `mariadb:10.5`) 96 * `DDEV_DATABASE_FAMILY`: Database "family" (example: `mysql`, `postgres`), useful for database connection URLs 97 * `DDEV_DOCROOT`: Relative path from approot to docroot 98 * `DDEV_GID`: The GID the web container runs as 99 * `DDEV_HOSTNAME`: Comma-separated list of FQDN hostnames 100 * `DDEV_HOST_DB_PORT`: Localhost port of the database server 101 * `DDEV_HOST_HTTPS_PORT`: Localhost port for HTTPS on web server 102 * `DDEV_HOST_MAILPIT_PORT`: Localhost port for Mailpit 103 * `DDEV_HOST_WEBSERVER_PORT`: Localhost port of the web server 104 * `DDEV_MAILPIT_HTTP_PORT`: Router Mailpit port for HTTP 105 * `DDEV_MAILPIT_HTTPS_PORT`: Router Mailpit port for HTTPS 106 * `DDEV_MUTAGEN_ENABLED`: `true` if Mutagen is enabled 107 * `DDEV_PHP_VERSION`: Current PHP version 108 * `DDEV_PRIMARY_URL`: Primary project URL 109 * `DDEV_PROJECT`: Project name, like `d8composer` 110 * `DDEV_PROJECT_STATUS`: Project status determined from the `web` and `db` services health, like `starting`, `running`, `stopped`, `paused`, or another status returned from Docker, including `healthy`, `unhealthy`, `exited`, `restarting` 111 * `DDEV_PROJECT_TYPE`: `backdrop`, `drupal`, `typo3`,`wordpress`, etc. 112 * `DDEV_ROUTER_HTTP_PORT`: Router port for HTTP 113 * `DDEV_ROUTER_HTTPS_PORT`: Router port for HTTPS 114 * `DDEV_SITENAME`: Project name, like `d8composer` 115 * `DDEV_TLD`: Top-level project domain, like `ddev.site` 116 * `DDEV_UID`: The UID the web container runs as 117 * `DDEV_WEBSERVER_TYPE`: `nginx-fpm`, `apache-fpm`, or `nginx-gunicorn` 118 * `GOARCH`: Architecture (`arm64`, `amd64`) 119 * `GOOS`: Operating system (`windows`, `darwin`, `linux`) 120 121 Useful variables for container scripts are: 122 123 * `DDEV_DOCROOT`: Relative path from approot to docroot 124 * `DDEV_FILES_DIR`: *Deprecated*, first directory of user-uploaded files 125 * `DDEV_FILES_DIRS`: Comma-separated list of directories of user-uploaded files 126 * `DDEV_HOSTNAME`: Comma-separated list of FQDN hostnames 127 * `DDEV_MUTAGEN_ENABLED`: `true` if Mutagen is enabled 128 * `DDEV_PHP_VERSION`: Current PHP version 129 * `DDEV_PRIMARY_URL`: Primary URL for the project 130 * `DDEV_PROJECT`: Project name, like `d8composer` 131 * `DDEV_PROJECT_TYPE`: `backdrop`, `drupal`, `typo3`,`wordpress`, etc. 132 * `DDEV_ROUTER_HTTP_PORT`: Router port for HTTP 133 * `DDEV_ROUTER_HTTPS_PORT`: Router port for HTTPS 134 * `DDEV_SITENAME`: Project name, like `d8composer` 135 * `DDEV_TLD`: Top-level project domain, like `ddev.site` 136 * `DDEV_WEBSERVER_TYPE`: `nginx-fpm`, `apache-fpm`, or `nginx-gunicorn` 137 * `IS_DDEV_PROJECT`: If `true`, PHP is running under DDEV 138 139 ## Annotations Supported 140 141 Custom commands support various annotations in the header for providing additional information to the user. 142 143 ### `Description` Annotation 144 145 `Description` should briefly describe the command in its help message. 146 147 Usage: `## Description: <command-description>` 148 149 Example: `## Description: my great custom command` 150 151 ### `Usage` Annotation 152 153 `Usage` should explain how to use the command in its help message. 154 155 Usage: `## Usage: <command-usage>` 156 157 Example: `## Usage: commandname [flags] [args]` 158 159 ### `Example` Annotation 160 161 `Example` should demonstrate how the command might be used. Use `\n` to force a line break. 162 163 Usage: `## Example: <command-example>` 164 165 Example: `## Example: commandname\ncommandname -h` 166 167 ### `Flags` Annotation 168 169 `Flags` should explain any available flags, including their shorthand when relevant, for the help message. It has to be encoded according the following definition: 170 171 If no flags are specified, the command will have its flags parsing disabled. Global flags like `--help` will not work unless the command supports them. 172 173 You can still do `ddev help <command>` to see the command's provided usage help. 174 175 Usage: `## Flags: <json-definition>` 176 177 This is the minimal usage of a flags definition: 178 179 Example: `## Flags: [{"Name":"flag","Usage":"sets the flag option"}]` 180 181 Output: 182 183 ```bash 184 Flags: 185 -h, --help help for ddev 186 -f, --flag sets the flag option 187 ``` 188 189 Multiple flags are separated by a comma: 190 191 Example: `## Flags: [{"Name":"flag1","Shorthand":"f","Usage":"flag1 usage"},{"Name":"flag2","Usage":"flag2 usage"}]` 192 193 Output: 194 195 ```bash 196 Flags: 197 -h, --help help for ddev 198 -f, --flag1 flag1 usage 199 --flag2 flag2 usage 200 ``` 201 202 The following fields can be used for a flag definition: 203 204 * `Name`: the name as it appears on command line 205 * `Shorthand`: one-letter abbreviated flag 206 * `Usage`: help message 207 * `Type`: possible values are `bool`, `string`, `int`, `uint` (defaults to `bool`) 208 * `DefValue`: default value for usage message 209 * `NoOptDefVal`: default value, if the flag is on the command line without any options 210 * `Annotations`: used by cobra.Command Bash autocomplete code (see <https://github.com/spf13/cobra/blob/main/site/content/completions/bash.md>) 211 212 ### `AutocompleteTerms` Annotation 213 214 If your command accepts specific arguments, and you know ahead of time what those arguments are, you can use this annotation to provide those arguments for autocompletion. 215 216 Usage: `## AutocompleteTerms: [<list-of-valid-arguments>]` 217 218 Example: `## AutocompleteTerms: ["enable","disable","toggle","status"]` 219 220 ### `CanRunGlobally` Annotation 221 222 This annotation is only available for global host commands. 223 224 Use `CanRunGlobally: true` if your global host command can be safely run even if the current working directory isn't inside a DDEV project. 225 226 This will make your command available to run regardless of what your current working directory is when you run it. 227 228 This annotation will have no effect if you are also using one of the following annotations: 229 230 * `ProjectTypes` 231 * `DBTypes` 232 233 Example: `## CanRunGlobally: true` 234 235 ### `ProjectTypes` Annotation 236 237 If your command should only be visible for a specific project type, `ProjectTypes` will allow you to define the supported types. This is especially useful for global custom commands. See [Quickstart for many CMSes](../../users/quickstart.md) for more information about the supported project types. Multiple types are separated by a comma. 238 239 Usage: `## ProjectTypes: <list-of-project-types>` 240 241 Example: `## ProjectTypes: drupal7,drupal,backdrop` 242 243 ### `OSTypes` Annotation (Host Commands Only) 244 245 If your host command should only run on one or more operating systems, add the `OSTypes` annotation. Multiple types are separated by a comma. Valid types are: 246 247 * `darwin` for macOS 248 * `windows` for Windows 249 * `linux` for Linux 250 251 Usage: `## OSTypes: <list-of-os-types>` 252 253 Example: `## OSTypes: darwin,linux` 254 255 ### `HostBinaryExists` Annotation (Host Commands Only) 256 257 If your host command should only run if a particular file exists, add the `HostBinaryExists` annotation. 258 259 Usage: `## HostBinaryExists: <path/to/file>` 260 261 Example: `## HostBinaryExists: /Applications/Sequel ace.app` 262 263 ### `DBTypes` Annotation 264 265 If your command should only be available for a particular database type, add the `DBTypes` annotation. Multiple types are separated by a comma. Valid types the available database types. 266 267 Usage: `## DBTypes: <type>` 268 269 Example: `## DBTypes: postgres` 270 271 ### `HostWorkingDir` Annotation (Container Commands Only) 272 273 If your container command should run from the directory you are running the command in the host, add the `HostWorkingDir` annotation. 274 275 Example: `## HostWorkingDir: true` 276 277 ### `ExecRaw` Annotation (Container Commands Only) 278 279 Use `ExecRaw: true` to pass command arguments directly to the container as-is. 280 281 For example, when `ExecRaw` is true, `ddev yarn --help` returns the help for `yarn`, not DDEV's help for the `ddev yarn` command. 282 283 We recommend using this annotation for all container commands. The default behavior is retained to avoid breaking existing commands. 284 285 Example: `## ExecRaw: true` 286 287 ## Known Windows Issues 288 289 ### Line Endings 290 291 If you’re editing a custom command to be run in a container, it must have LF line endings and not traditional Windows CRLF line endings. Remember that a custom command in a container is a script that must execute in a Linux environment. 292 293 ### Bash 294 295 Commands can’t be executed if DDEV can’t find `bash`. If you’re running inside Git Bash in most any terminal, this shouldn’t be an issue, and DDEV should be able to find `git-bash` if it’s in `C:\Program Files\Git\bin` as well. But if neither of those is true, add the directory of `bash.exe` to your `PATH` environment variable.