Defining an additional service with Docker Compose
Prerequisite knowledge
Much of ddev's customization ability and extensibility comes from leveraging features and functionality provided by Docker and Docker Compose. Some working knowledge of these tools is required in order to customize or extend the environment ddev provides.
There are many examples of custom Docker compose files available on ddev-contrib.
Background
Under the hood, ddev uses docker-compose to define and run the multiple containers that make up the local environment for a project. docker-compose supports defining multiple compose files to facilitate sharing Compose configurations between files and projects, and ddev is designed to leverage this ability.
To add custom configuration or additional services to your project, create docker-compose files in the .ddev
directory for your project. ddev will process any files using the docker-compose.[servicename].yaml
naming convention and include them in executing docker-compose functionality. Optionally you can also create a docker-compose.override.yaml
to override any configurations from the main .ddev/.ddev-docker-compose-base.yaml
or any additional docker-compose files added to your project.
Restrictions on the .ddev/.ddev-docker-compose-base.yaml file
The main docker-compose file is named .ddev/.ddev-docker-compose-base.yaml
and exclusively reserved for ddev's use; it is overwritten every time a project is started, so it should not be edited because edits will be lost. If you need to override configuration provided by .ddev/.ddev-docker-compose-base.yaml, use an additional file "docker-compose.
docker-compose.*.yaml examples
- Expose an additional port 9999 to host port 9999, in a file perhaps called
docker-compose.ports.yaml
:
version: '3.6'
services:
web:
ports:
- "9999:9999"
Confirming docker-compose configurations
To better understand how ddev is parsing your custom docker-compose files, you can run ddev debug compose-config
to print the final docker-compose configuration as generated by ddev when starting your project.
Conventions for defining additional services
When defining additional services for your project, we recommended you follow these conventions to ensure ddev handles your service the same way ddev handles default services.
-
To name containers follow this naming convention
ddev-[projectname]-[servicename]
-
Provide containers with the following labels
-
com.ddev.site-name: ${DDEV_SITENAME}
-
com.ddev.approot: $DDEV_APPROOT
-
-
Exposing ports for service: you can expose the port for a service to be accessible as
projectname.ddev.site:portNum
while your project is running. This is achieved by the following configurations for the container(s) being added:-
Define only the internal port in the
ports
section for docker-compose. ThehostPort:containerPort
convention normally used to expose ports in docker should not be used here, since we are leveraging the ddev router to expose the ports. -
To expose a web interface to be accessible over HTTP, define the following environment variables in the
environment
section for docker-compose:VIRTUAL_HOST=$DDEV_HOSTNAME
HTTP_EXPOSE=portNum
ThehostPort:containerPort
convention may be used here to expose a container's port to a different external port. To expose multiple ports for a single container, define the ports as comma-separated values.HTTPS_EXPOSE=<exposedPortNumber>:portNum
This will expose an https interface on<exposedPortNumber>
to the host (and to the web container) ashttps://<project>.ddev.site:exposedPortNumber
. To expose multiple ports for a single container, use comma-separated definitions, as inHTTPS_EXPOSE=9998:80,9999:81
, which would expose http port 80 from the container ashttps://<project>.ddev.site:9998
and http port 81 from the container ashttps://<project>.ddev.site:9999
.
-
-
Naming volumes for persistent data: A volume with persistent data should have the same name as the service and should not have a custom name. For example, the persistent volume for the Postgres service has:
yaml volumes: postgres:
and as a result will end up with a volume named ddev-<projectname>_postgres
; this default volume name will be automatically deleted by ddev if you do a ddev delete
or ddev stop --remove-data
.
Interacting with additional services
ddev exec
, ddev ssh
, and ddev logs
interact with containers on an individual basis. By default, these commands interact with the web container for a project. All of these commands, however, provide a --service
or -s
flag allowing you to specify the service name of the container you want to interact with. For example, if you added a service to provide Apache Solr, and the service was named solr
, you would be able to run ddev logs --service solr
to retrieve the logs of the Solr container.