loading...
Cover image for Lando configuration for Drupal module development

Lando configuration for Drupal module development

ericpugh profile image ericpugh Originally published at ericpugh.dev on ・4 min read

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 ✔️, forgot about it for a couple years, update a patch version ✔️,
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 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
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 to get you started.

Assumptions

I'm assuming you have Lando installed and a Drupal (8.8 or higher)
project installed with composer, and have required drupal/core-dev
and 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 lando start. 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.

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, 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.

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?)

Discussion

pic
Editor guide