Lando configuration for Drupal module development
Tags: drupal, lando
Published: 2020-03-09 01:28:22

---
title: Lando configuration for Drupal module development
published: true
date: 2020-03-01 00:00:00 UTC
tags: drupal, lando
cover_image: https://ericpugh.dev/images/1-lando/lando-cover.png
canonical_url: https://ericpugh.dev/2020/my-drupal-lando-config/
---

For PHP developers I don't remember managing your local environment being quite as big an issue as it has been lately.
It used to be, install PHP 5.6 :heavy_check_mark:, forgot about it for a couple years, update a patch version :heavy_check_mark:, 
a couple more years go by. That's changed since the release of PHP 7. I've been consistently having to test more on 
different PHP minor versions, 7.2, 7.3, etc. Don't get me wrong, this is a good thing, but it also means that our dev tools
have gotten more complex (and better). I was a long time MAMP user, then a long time Vagrant user, and have more recently
been using [Lando](https://lando.dev/) for basically _all_ of my (frontend/backend) local development.

## What's this _Lando_ you speak of?

Lando is an Open Source (docker powered) tool that creates a configurable local development environment per project. Basically, my
understanding is that it's an abstraction of Docker Compose, that allows you to add a simple ".lando.yml" [config file](https://docs.lando.dev/config/lando.html#landofile) 
in your project root defining an environment. Dead simple or complex environments with database, cache, or indexing services,
Lando takes care of the hard part of managing versions/images and wiring all those services together. It's completely customizable
and has a bunch of [recipes](https://docs.lando.dev/config/recipes.html#usage) to get you started.

## Assumptions

I'm assuming you have [Lando installed](https://docs.lando.dev/basics/installation.html) and a Drupal (8.8 or higher) 
project installed with composer, and have required [drupal/core-dev](https://packagist.org/packages/drupal/core-dev) 
and [mglaman/drupal-check](https://packagist.org/packages/mglaman/drupal-check) in your dev requirements. I'm also assuming 
you know what all that means.

## The .lando.yml

So, to get started you'd just create this ".lando.yml" file in your project root, and run <code class="inline-code">lando start</code>. When it's 
finish building the drupal site would be available at _example.lndo.site_. (or whatever "name" you specified). Here's the 
file with a brief explanation following.

```yml
name: example
recipe: drupal8
config:
  webroot: web
  php: '7.3'
  via: nginx
  database: mariadb:10.3
  drush: "*"
  xdebug: true
services:
  appserver:
    cmd: drush --root=/app/web
    build:
      - "composer global require drupal/coder"
      - "/app/vendor/bin/phpcs --config-set installed_paths /app/vendor/drupal/coder/coder_sniffer"
    build_as_root:
      - apt-get update -y && apt-get install vim -y
      - echo "Updating PHP-FPM settings ..."
      - sed -i 's/pm.max_children = 5/pm.max_children = 256/g' /usr/local/etc/php-fpm.d/www.conf
      - sed -i 's/pm.min_spare_servers = 1/pm.min_spare_servers = 32/g' /usr/local/etc/php-fpm.d/www.conf
      - sed -i 's/pm.max_spare_servers = 3/pm.max_spare_servers = 64/g' /usr/local/etc/php-fpm.d/www.conf
      - sed -i 's/pm.start_servers = 2/pm.start_servers = 64/g' /usr/local/etc/php-fpm.d/www.conf
      - sed -i 's/;pm.max_requests = 500/pm.max_requests = 500/g' /usr/local/etc/php-fpm.d/www.conf
  cache:
    type: redis
    portforward: true
    persist: true
  pma:
    type: phpmyadmin
    hosts:
      - database
  nodejs:
    type: node:10
    ssl: false
    globals:
      gulp-cli: latest
proxy:
  pma:
    - phpmyadmin.lndo.site
tooling:
  node:
    service: nodejs
  npm:
    service: nodejs
  npx:
    service: nodejs
  redis-cli:
    service: cache
  nano:
    service: appserver
  vi:
    service: appserver
  vim:
    service: appserver
  drupalcs:
    service: appserver
    cmd: "/app/vendor/bin/phpcs --standard=Drupal,DrupalPractice"
    description: Run phpcs Drupal Coding Standards against a given file or directory.
  drupalcbf:
    service: appserver
    cmd: "/app/vendor/bin/phpcbf --standard=Drupal"
    description: Automatically fix Drupal coding standards suggestions.
  phpunit:
    service: appserver
    cmd: vendor/bin/phpunit --configuration web/core
    description: Run PHPUnit tests on a specific file or Drupal module.
  drupal-check:
    service: appserver
    cmd: vendor/bin/drupal-check -ad
    description: Check Drupal code for deprecations and discover bugs via static analysis.
events:
  pre-start:
    - appserver: composer install
    - nodejs: npm install
  post-start:
    - cat /app/etc/welcome.txt
```

## Explanation

This is mostly just the standard [drupal8 recipe](https://docs.lando.dev/config/drupal8.html), but there are a couple of things you're
going to use often when developing Drupal modules. First, notice under services I've added a couple of custom commands to 
be executed on the service when it starts up. These commands install and configure code sniffer, so it can be used in tooling.

```yml
services:
  appserver:
    cmd: drush --root=/app/web
    build:
      - "composer global require drupal/coder"
      - "/app/vendor/bin/phpcs --config-set installed_paths /app/vendor/drupal/coder/coder_sniffer"
```
 
The "tooling" section sets a couple commands with default options that can be run with the "lando" command, which executes
those commands in the container.
 
Run Code Sniffer against your custom module: 
 
```
lando drupalcs web/modules/custom/example_module/
```

Run Code Beautifier and Fixer to automatically fix coding standards issues:


```
lando drupalcbf web/modules/custom/example_module/
```

Run static analysis tool "Drupal Check" to test code for "correctness":

```
lando drupal-check web/modules/custom/example_module/
```

Run unit tests:

```
lando phpunit web/modules/custom/example_module/
```

That's mostly it. I haven't included it here, but I usually also add a command under tooling for a custom symfony console
package that I use for different local development tasks. (Mostly, just chaining Drush commands together to pull a database,
import configuration, etc.). That might be something for another post. Also, under the "post-start" event, I usually add 
a "welcome.txt" file with ASCII art that will output to the console when Lando starts up... just a little something to amuse 
your colleagues with. (**why** are they never amused?)