Custom (Shell) Commands¶
It's quite easy to add custom commands to ddev; they can execute either on the host or in the various containers. The basic idea is to add a bash script to either the specific project in .ddev/commands/host
or .ddev/commands/<containername>
or globally for every project in ~/.ddev/commands
There are example commands provided in ddev/commands/*/*.example
that can just be copied or moved (or symlinked) and used as commands. For example, .ddev/commands/host/mysqlworkbench.example can be used to add a "ddev mysqlworkbench" command, just change it from "mysqlworkbench.example" to "mysqlworkbench". If you're on macOS or Linux (or some configurations of Windows) you can just cd .ddev/commands/host && ln -s mysqlworkbench.example mysqlworkbench
. Also, a new ddev mysql
command has been added using this technique (as a db container command). Also see the ddev mysql command.
Notes for all command types¶
- The command filename is not what determines the name of the command. That comes from the Usage doc line (
## Usage: commandname
). - To confirm that your custom command is available, run
ddev -h
, and look for it in the list.
Host commands¶
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:
#!/usr/bin/env bash
## Description: Open PhpStorm with the current project
## Usage: phpstorm
## Example: "ddev phpstorm"
# Example is macOS-specific, but easy to adapt to any OS
open -a PhpStorm.app ${DDEV_APPROOT}
Container commands¶
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,
In addition to commands that run in the standard ddev containers like "web" and "db", you can run commands in custom containers, just using the service name, like .ddev/commands/solr/<command>
. Note, however, that your service must mount /mnt/ddev_config as the web and db containers do, so the volumes
section of docker-compose.<servicename>.yaml
needs:
For example, to add a solrtail
command that runs in a solr service, add .ddev/commands/solr/solrtail
with:
#!/bin/bash
## Description: Tail the main solr log
## Usage: solrtail
## Example: ddev solrtail
tail -f /opt/solr/server/logs/solr.log
Global commands¶
Global commands work exactly the same as project-level commands, you just have to put them in your global .ddev directory. Your home directory has a .ddev/commands in it; there you can add host or web or db commands.
Shell Command Examples¶
There are many examples of global and project-level custom/shell commands that are provided directly by DDEV, and you can adapt these to your 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 shows simple argument processing and the launch command demonstrates flag processing.
Environment variables provided¶
A number of environment variables are provided to the script. These are generally supported, but please avoid using undocumented environment variables. Useful variables for host scripts are:
DDEV_APPROOT
: file system location of the project on the hostDDEV_DATABASE
: database in use, in formattype:version
, for examplemariadb:10.5
.DDEV_DOCROOT
: Relative path from approot to docrootDDEV_HOSTNAME
: Comma-separated list of FQDN hostnamesDDEV_HOST_DB_PORT
: Localhost port of the database serverDDEV_HOST_HTTPS_PORT
: Localhost port for https on webserverDDEV_HOST_WEBSERVER_PORT
: Localhost port of the webserverDDEV_PHP_VERSION
: PHP version runningDDEV_PRIMARY_URL
: Primary URL for the projectDDEV_PROJECT
: Project name, like "d8composer"DDEV_PROJECT_TYPE
: drupal8, typo3, backdrop, wordpress, etc.DDEV_ROUTER_HTTP_PORT
: Router port for httpDDEV_ROUTER_HTTPS_PORT
: Router port for httpsDDEV_SITENAME
: Project name, like "d8composer".DDEV_TLD
: Top-level domain of project, like "ddev.site"DDEV_WEBSERVER_TYPE
: nginx-fpm, apache-fpm`GOARCH
: architecture: "arm64", "amd64"GOOS
: operating system: "windows", "darwin", "linux"
Useful variables for container scripts are:
DDEV_DOCROOT
: Relative path from approot to docrootDDEV_FILES_DIR
: Directory of user-uploaded filesDDEV_HOSTNAME
: Comma-separated list of FQDN hostnamesDDEV_PHP_VERSION
: PHP version runningDDEV_PRIMARY_URL
: Primary URL for the projectDDEV_PROJECT
: Project name, like "d8composer"DDEV_PROJECT_TYPE
: drupal8, typo3, backdrop, wordpress, etc.DDEV_ROUTER_HTTP_PORT
: Router port for httpDDEV_ROUTER_HTTPS_PORT
: Router port for httpsDDEV_SITENAME
: Project name, like "d8composer".DDEV_TLD
: Top-level domain of project, like "ddev.site"DDEV_WEBSERVER_TYPE
: nginx-fpm, apache-fpmIS_DDEV_PROJECT
: if set to "true" it means that php is running under DDEV
Annotations supported¶
The custom commands support various annotations in the header which are used to provide additional information about the command to the user.
"Description" annotation¶
Description
is used for the listing of available commands and for the help message of the custom command.
Usage: ## Description: <command-description>
Example: ## Description: my great custom command
"Usage" annotation¶
Usage
is used for the help message to provide an idea to the user how to use this command.
Usage: ## Usage: <command-usage>
Example: ## Usage: commandname [flags] [args]
"Example" annotation¶
Example
is used for the help message to provide some usage examples to the user. Use \n
to force a line break.
Usage: ## Example: <command-example>
Example: ## Example: commandname\ncommandname -h
"Flags" annotation¶
Flags
is used for the help message. All defined flags here are listed with their shorthand if available. It has to be encoded according the following definition:
Usage: ## Flags: <json-definition>
This is the minimal usage of a flags definition:
Example: ## Flags: [{"Name":"flag","Usage":"sets the flag option"}]
Output:
Multiple flags are separated by a comma:
Example: ## Flags: [{"Name":"flag1","Shorthand":"f","Usage":"flag1 usage"},{"Name":"flag2","Usage":"flag2 usage"}]
Output:
The following fields can be used for a flag definition:
Name
: the name as it appears on command lineShorthand
: one-letter abbreviated flagUsage
: help messageType
: possible values arebool
,string
,int
,uint
(defaults to bool)DefValue
: default value for usage messageNoOptDefVal
: default value, if the flag is on the command line without any optionsAnnotations
: used by cobra.Command bash autocomplete code see https://github.com/spf13/cobra/blob/master/bash_completions.md
"ProjectTypes
" annotation¶
If your command should only be visible for a particular project type, ProjectTypes
will allow you to define the supported types. This is especially useful for global custom commands. See https://ddev.readthedocs.io/en/stable/users/cli-usage/#quickstart-guides for more information about the supported project types. Multiple types are separated by a comma.
Usage: ## ProjectTypes: <list-of-project-types>
Example: ## ProjectTypes: drupal7,drupal8,drupal9,backdrop
"OSTypes
" annotation (host commands only)¶
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:
darwin
for macOSwindows
for Windowslinux
for Linux
Usage: ## OSTypes: <list-of-os-types>
Example: ## OSTypes: darwin,linux
"HostBinaryExists
" annotation (host commands only)¶
If your host command should only run if a particular file exists, add the HostBinaryExists
annotation.
Usage: ## HostBinaryExists: <path/to/file>
Example: ## HostBinaryExists: /Applications/Sequel ace.app
"DBTypes
" annotation¶
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.
Usage: ## DBTypes: <type>
Example: ## DBTypes: postgres
Known Windows OS issues¶
- Line Endings: If you are editing a custom command which will run in a container, it must have LF line endings (not traditional Windows CRLF line endings). Remember that a custom command in a container is a script that must execute in a Linux environment.
- If ddev can't find "bash" to execute it, then the commands can't be used. If you are 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.