Skip to content


The docker-compose.yml file is used by Lagoon to:

  • Learn which services/containers should be deployed.
  • Define how the images for the containers are built.
  • Define additional configurations like persistent volumes.

Docker-compose (the tool) is very strict in validating the content of the YAML file, so we can only do configuration within labels of a service definition.


Lagoon only reads the labels, service names, image names and build definitions from a docker-compose.yml file. Definitions like: ports, environment variables, volumes, networks, links, users, etc. are IGNORED.

This is intentional as the docker-compose file is there to define your local environment configuration. Lagoon learns from the lagoon.type the type of service you are deploying and from that knows about ports, networks and any additional configuration that this service might need.

Here a straightforward example of a docker-compose.yml file for Drupal:

version: '2.3'

  # Lagoon project name (leave `&lagoon-project` when you edit this)
  &lagoon-project drupal-example

    # Define all volumes you would like to have real-time mounted into the docker containers
      - .:/app:delegated

    LAGOON_PROJECT: *lagoon-project
    # Route that should be used locally, if you are using pygmy, this route *must* end with
    # Uncomment if you like to have the system behave like in production
    # Uncomment to enable xdebug and then restart via `docker-compose up -d`
    #XDEBUG_ENABLE: "true"

    # The default user under which the containers should run. Change this if you are on linux and run with another user than id `1000`
    user: '1000'


      context: .
      dockerfile: nginx.dockerfile
      lagoon.type: nginx-php-persistent
      lagoon.persistent: /app/web/sites/default/files/

      context: .
      dockerfile: php.dockerfile
      lagoon.type: nginx-php-persistent nginx
      lagoon.persistent: /app/web/sites/default/files/

    image: amazeeio/mariadb-drupal
      lagoon.type: mariadb

Basic settings#


This is the machine name of your project, define it here. We’ll use “drupal-example.”


This tells Lagoon what to mount into the container. Your web application lives in /app, but you can add or change this if needed.


  1. Here you can set your local development url. If you are using pygmy, it must end with
  2. If you want to exactly mimic the production environment, uncomment LAGOON_ENVIRONMENT_TYPE: production.
  3. If you want to enable xd-ebug, uncomment DEBUG_ENABLE: "true".


You are unlikely to need to change this, unless you are on Linux and would like to run with a user other than 1000.


This defines all the services you want to deploy. Unfortunately, docker-compose calls them services, even though they are actually containers. Going forward we'll be calling them services, and throughout this documentation.

The name of the service (nginx, php, and mariadb in the example above) is used by Lagoon as the name of the Kubernetes pod (yet another term - again, we'll be calling them services) that is generated, plus also any additional Kubernetes objects that are created based on the defined lagoon.type, which could be things like services, routes, persistent storage, etc.

Docker Images#


If you want Lagoon to build a Dockerfile for your service during every deployment, you can define it here:


  • context
  • The build context path that should be passed on into the docker build command.
  • dockerfile:
  • Location and name of the Dockerfile that should be built.


Lagoon does NOT support the short version of build: <Dockerfile> and will fail if it finds such a definition.


If you don't need to build a Dockerfile and just want to use an existing Dockerfile, define it via image.


Lagoon needs to know what type of service you are deploying in order to configure the correct Kubernetes and OpenShift objects.

This is done via the lagoon.type label. There are many different types to choose from. Check Service Types to see all of them and their additional configuration possibilities.

Skip/Ignore containers#

If you'd like Lagoon to ignore a service completely - for example, you need a container only during local development - give it the type none.

Persistent Storage#

Some containers need persistent storage. In many cases, Lagoon knows where that persistent storage needs to go. For example, for a MariaDB container, Lagoon knows that the persistent storage should be put into /var/lib/mysql , and puts it there automatically without any extra configuration to define that. For some situations, though, Lagoon needs your help to know where to put the persistent storage:

  • lagoon.persistent - The absolute path where the persistent storage should be mounted (the above example uses /app/web/sites/default/files/ which is where Drupal expects its persistent storage).
  • - Tells Lagoon to not create a new persistent storage for that service, but instead mounts the persistent storage of another defined service into this service.
  • lagoon.persistent.size - The size of persistent storage you require (Lagoon usually gives you minimum 5G of persistent storage, if you need more, define it here).
  • lagoon.persistent.class - By default Lagoon automatically assigns the right storage class for your service (like SSDs for MySQL, bulk storage for Nginx, etc.). If you need to overwrite this, you can do so here. This is highly dependent on the underlying Kubernetes/OpenShift that Lagoon runs on. Ask your Lagoon administrator about this.

Multi-Container Pods#

Kubernetes and OpenShift don't deploy plain containers. Instead, they deploy pods, with each one or more containers. Usually Lagoon creates a single pod with a container inside for each defined docker-compose service. For some cases, we need to put two containers inside a single pod, as these containers are so dependent on each other that they should always stay together. An example for such a situation is the PHP and Nginx containers that both contain PHP code of a web application like Drupal.

For these cases, it is possible to tell Lagoon which services should stay together, which is done in the following way (remember that we are calling containers services because of docker-compose:

  1. Define both services with a lagoon.type that expects two services (in the example this is nginx-php-persistent defined on the nginx and php services).
  2. Link the second service with the first one, defining the label of the second one with the first one. (in the example this is done with defining nginx).

This will cause Lagoon to realize that the nginx and php containers are combined in a pod that will be called nginx.

Lagoon still needs to understand which of the two services is the actual individual service type (nginx and php in this case). It does this by searching for service names with the same name that are given by the type, so nginx-php-persistent expects one service with the name nginx and one with php in the docker-compose.yml. If for any reason you want to use different names for the services, or you need for than one pod with the type nginx-php-persistent there is an additional label lagoon.deployment.servicetype which can be used to define the actual service type.

An example:

      context: .
      dockerfile: nginx.dockerfile
      lagoon.type: nginx-php-persistent
      lagoon.persistent: /app/web/sites/default/files/ nginx # If this isn't present, Lagoon will use the container name, which in this case is nginx.
      lagoon.deployment.servicetype: nginx
      context: .
      dockerfile: php.dockerfile
      lagoon.type: nginx-php-persistent
      lagoon.persistent: /app/web/sites/default/files/ nginx # We want this service be part of the nginx pod in Lagoon.
      lagoon.deployment.servicetype: php

In the example above, the services are named nginx and php (but you can call them whatever you want). The tells Lagoon which services go together - all of the services with the same name go together.

In order for Lagoon to realize which one is the nginx and which one is the php service, we define it via lagoon.deployment.servicetype: nginx and lagoon.deployment.servicetype: php.

Custom Templates (Openshift only)#

OpenShift defines templates as follows:

A template describes a set of objects that can be parameterized and processed to produce a list of objects for creation by OpenShift Container Platform. A template can be processed to create anything you have permission to create within a project, for example services, build configurations, and DeploymentConfigs. A template may also define a set of labels to apply to every object defined in the template.

Lagoon comes with a variety of pre-defined templates, which set all kinds of needed configuration in YAML files. Check out the shipped templates from the templates folder of oc-build-deploy-dind.

If you need to make changes to the OpenShift templates, you can define your own template via lagoon.template.


The template is called with oc process, so you should define the same parameters as seen in the default templates.

You can also overwrite the templates for a specific environment. This is done in .lagoon.yml

Helm Templates (Kubernetes only)#

Lagoon uses Helm for templating on Kubernetes. To do this, a series of Charts are included with the kubectl-build-deploy-dind service.

Custom Rollout Monitor Types#

By default , Lagoon expects that services from custom templates are rolled out via a DeploymentConfig object within Openshift/Kubernetes. It monitors the rollout based on this object. In some cases, the services that are defined via custom deployment need a different way of monitoring. This can be defined via lagoon.rollout:

  • deploymentconfig - This is the default. Expects a DeploymentConfig object in the template for the service.
  • statefulset - Expects a Statefulset object in the template for the service.
  • daemonset - Expects a Daemonset object in the template for the service.
  • false - Will not monitor any rollouts, and will just be happy if the template applies and does not throw any errors.

You can also overwrite the rollout for just one specific environment. This is done in .lagoon.yml.