Spring 2021 Test Drive!

Installing Lando in WSL 2

Using the latest Docker Desktop 3.2.x and Ubuntu 18.04

Callback Insanity
9 min readMar 15, 2021

My main driver in WSL2 is usually Alpine, but I’ve initially encountered some issues with installing Lando there. Alpine is not for the weak! Instead I am going to use Ubuntu (18.04) in WSL2, and install Lando there.



Back in Lando Github issue #2781, some users were complaining how Docker Desktop automatically updates to the latest version, sometimes breaking Lando integration.

For context, when you first install Lando, Lando installs Docker Desktop for you. But that’s not all, Lando installs a specific version of Docker Desktop, a.k.a. not the latest.

As a person that has been working with containers 100% since at least 2017 I’ve always run the latest version of Docker Desktop locally to get the latest features. Having someone tell me to run an older version of DD for me would be a non-starter, and so today I was fixin’ to try and run Lando with my own version of Docker Desktop and not the old one installed my Lando.

Lando Github issue #1723 provided some hope and ideas of using Lando with custom, non-Lando managed versions of Docker, and so yours truly had to go and investigate. Henceforth this story!

TL;DR: It’s possible to use the latest Docker Desktop (3.2.x) with Lando on WSL2.

Install Lando from Github

First off, I assume that you have the latest Docker for Windows installed, along with WSL2, and in this case Ubuntu 18.04 or similar version.

Here I open a Windows Terminal into my local Ubuntu WSL and follow the rest of the instructions below.

Download the latest Lando .deb package (v3.0.26) from the Lando releases in Github:

Download latest stable Lando release.

Installing the Lando package, and ignore the Docker dependency in the process (Docker for Windows is already installed):

Installing the Lando executable using a .deb package (in Ubuntu WSL2).

Confirm that you can Lando without any errors or warnings popping up:

Testing Lando executable, successful.

As you can see, the .deb package has installed Lando into the directory /usr/local/bin/lando.

Fire Up Lando

Create an example Lando stack

Examples can be taken from here.

Example Lando .lando.yml configuration.

Start our hello world example:

Launching Lando project from Ubuntu WSL2.

Command lando start seems to have completed without any major errors or warnings:

Launching Lando project successful.

If you click on one of the APPSERVER URLS, in my example https://localhost:51467, my browser automatically pops up with the address pre-populated.

A warning due to the HTTPS certificate not being trusted shows up, but I click on Advanced -> Proceed to localhost.

The results is the following:

Empty Apache directory is sad 😩

There is nothing present in the Apache web server, because Lando did not install Drupal.

Open Docker Desktop and exec into the Lando appserver container:

Using Docker for Windows to Exec into container.

By clicking on the CLI button that throws you into an interactive shell of the appserver container:

The Lando PHP container.

There we can run a couple of diagnostics and confirm that the directory is indeed empty:

However, you can see a lonely .lando.yml file. That’s because that file got mounted from the WSL directory /home/wsl/drupal1 into the /app path in the container.

Installing Drupal with Composer

First confirm that Composer is installed in the container and it’s version:

Checking Composer version inside Lando container.

Installing Drupal with Composer has been covered like a beaten dead horse everywhere else in the webs, so need not I got into detail. But the official documents for installing Drupal w/ Composer are here.

The template for Drupal 8/9 is:

composer create-project drupal/recommended-project my_site_name_dir

In my case I want to install to the current directory, because that’s already mounted by Lando from WSL into the Docker container, and that’s where Apache is looking for an index.php:

composer create-project drupal/recommended-project .

Compose does not let me install the latest Drupal version (9.x) because the Drupal recipe I used in my .lando.yml installs PHP 7.3.x or greater, and the Lando Drupal recipe uses PHP 7.2.34. Here’s the complaint from Composer:

Cleanup any artifacts and re-try Drupal install with older version:

Make sure the /app directory is completely empty before any composer commands.

This time the Composer installer has a little more luck:

composer create-project drupal/recommended-project:8.x .

And installs the latest version of Drupal 8.x, in this case version 8.9.13:

Composer install is successful.

Here are the results:

Contents of /app directory after composer install.

Now if I revisit the URL Lando gave me for my app, I get some contents:

And if I click on web, I get a Drupal install page:

The initial Drupal install page.

Running the Drupal database installer

When you exec into the Lando appserver container, you are exec’d in as root. The Apache server running inside the container expects files to be owned by www-data. If you install Drupal with Composer using root like I did, Drupal is not going to be able to write any initial directories it needs.

Using root is evil!

The easiest way to solve that is to chown the whole app directory into www-data:www-data:

Updating permissions on the container.

After doing that and refreshing the Drupal installer, the verify requirements page has automatically gone away (meaning Drupal was able to create any setup files it needed inside the container). Now I am presented with the Database setup page:

The Drupal installer page.

Configuring the database

TBH I don’t know what the database credentials are. And since I’m a developer that obviously means I’m never going to read the fine manual, hashtag #RTFM.

So I just do a good ‘ol exec into the MySQL container and do some investigation:

Exec into the database container using the Docker Desktop GUI

Bingo! Lando set ups the database with the user root, and no password (you can see here that using password root failed):

Inspecting the Lando database container.

As part of the Lando drupal recipe, it seems that a database named drupal7 was created. Luckily that’s how far Lando went, and the drupal7 database is empty, meaning that we can use it for our Drupal install.

Using Docker for Windows, I can inspect the database container created by Lando, and see some useful environment variables that probably indicate what parameters I can use for setting up Drupal:

Inspecting the Lando database container.

Of interest here are four environment variables:

  • MYSQL_DATABASE: The name of the database to use for Drupal.
  • MYSQL_PASSWORD: The database password to pass to Drupal.
  • MYSQL_USER: The database user to give Drupal.
  • LANDO_SERVICE_NAME: The name, or address of the database server that the PHP container running Drupal is going to use to contact the database. Usually this could be something like localhost or 127.0.01, but because the database is not running “locally” inside the PHP container, it needs another address.

Lando uses Docker Compose in the background to orchestrate Docker services. In fact, Lando is a big Docker Compose wrapper. When using Docker Compose, services usually have a name. This name is then associated with each services’ container, and accessible to other containers in the Docker network, assuming that service exposes any ports to other containers.

In this case, the database service name is database. Meaning the PHP container running Drupal will be able to talk to MySQL/MariaDB on the database:3306 address.

The values for the database installer are:

  • Database name: drupal7
  • Database username: drupal7
  • Database password: drupal7
  • Database host: database

I leave the port to the default number 3306.

Here are the parameters populated on the Drupal installer page:

Populating the database installer with Lando values.

Those parameters are successful, and I can see that Drupal is installed into the database:

Database credentials are legit!

After the installer completes, I am logged into my brand new Drupal 8.x site, running inside Docker for Windows, with containers provided by Lando, and launched from WSL 2 Ubuntu:

Drupal 8.x install is successful!

Reader Questions

I never intended this story to be an in-depth, exhaustive dive into Lando and it’s plethora of configuration options or recipes. So I glossed over some details that perhaps I can cover in a later post or even better, you can answer in the comments below!

  • What happens when you destroy your Lando stack? Do you lose the database?
  • Is there a Lando recipe that works better for Drupal 9? Such as having a newer PHP version installed in the Lando container?
  • How do you use XDebug with this Lando configuration?
  • And lest I forget, where is my Alpine setup 😠 !??!

Here are some hints:

  • For the database I don’t see anything on the barebones Lando recipe I used that says to mount a local WSL directory as a mount path into the database /var/lib/mysql directory. That probably means your precious database (and all your billable hours) are gone when you destroy the database container. Have fun!
  • The Lando documentation has recipes for all kinds of PHP frameworks and hosting providers. Here is a recipe for Drupal 9.
  • As for XDebug, I’ll give you a head start with this document. Note that’s for PHPStorm, good luck with Visual Studio Code and WSL2!
  • And finally, I’m still investigating how to get a similar setup working on Alpine WSL. Like I said at the beginning of this story I ran into some initial issues there and it’s something I’m hoping to triage sooner than later!

Also I’m aware that there’s better ways to use the facilities provided by Lando such as Composer automation functions that install Drupal for you — but I wanted to see how far I could get away with as little as possible. Sometimes for me the less magic I use allows me to understand the base system better. But that’s just me.

From Callback Insanity, Happy Dockerizing, and here’s to a better 2021 for everyone!



Callback Insanity

Organic, fair-sourced DevOps and Full-Stack things. This is a BYOB Establishment — Bring Your Own hipster Beard.