Running a site in Lando

Fragment block

Alleen een AI-systeem dat het vermogen heeft om
Default blog

Why?

While in theory it is possible to maintain different versions of PHP on your local development machine, it is something that will cost you a lot of time, and, maybe more important, each of your colleagues will also be forced to invest a lot of time in keeping her development machine up to date. In the past years a lot of effort was put in to this problem by a lot of people in a multitude of communities. And, as it goes with this kind of developments, a number of solutions are presented as THE solution and I am sure that for anyone who is using a certain solution, this solution is THE solution. I have chosen to use Lando, because I like the documentation that is available on, for example, Lando and because of the enthusiastic talk Liberté, égalité, fraternité: Local development in Docker containers with Lando given by my former colleague Daniël Smidt and Jeffrey Bertoen at the 2018 DrupalJam.  

Memory lane

The way I handled the problem of different PHP versions for different projects (on Ubuntu / Linux Mint) was a combination of installing the correct software packages and a number of local bash-scripts. To get the correct packages I used the infamous 'ondrej' package repository. To use this repository add it to your system with $ sudo apt install python-software-properties $ sudo add-apt-repository ppa:ondrej/php $ apt update Installing a specific PHP version will now be as easy as: $ sudo apt install php7.1 To use this version of PHP I locally used a script called setPHP71.sh with the following content: # !/bin/sh sudo update-alternatives --set php /usr/bin/php7.1 sudo a2dismod php5.6 sudo a2dismod php7.0 sudo a2enmod php7.1 sudo service apache2 restart Although this seems to be a reasonable situation, if you look somewhat better at the scripts a number of problems will become clear. First, I am not a very skilled bash-shell programmer, otherwise I would have created a script that takes the desired PHP version as argument instead of creating a separate script for each PHP version. A second problem is that I need a line like sudo a2dismod php<X> for each installed PHP version. This is maintainable if you have two or three PHP versions but will become a bit of a mess if the number of versions grows. But the largest drawback of this approach is that I will somehow have to remember which PHP version to use for which project and, to prevent endless searches to the most obscure problems, remember to activate that version when starting to work on that project. And all of this also holds true for any of my colleagues... And this only solves the problem of multiple PHP versions, what about Apche, nginx, MySQL, MariaDB and maybe even different OS-version? This will become very ugly very fast.  

Lando setup

So I, inspired by the talk on DrupalJam mentioned above, I started to look to an alternative way of coping with the multiple environments problem. Of course I could have used a "plain" docker setup but there are a number of clear advantages using something like Lando, which are clearly explained in the talk and also on the lando site. Installing Lando is also explained at INSTALLING on the Lando site, but I run into a number of problems on my Linux Mint / Ubuntu system which I will elaborate here.

Docker says no...

After installing docker following the recipe at the docker documentation site I tried to run the 'hello wold'-example and got: $ docker run hello-world docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.38/containers/create: dial unix /var/run/docker.sock: connect: permission denied. See 'docker run --help'. After some research I found that this was caused by ther permissions set during installation. It was easily repaired with the following commands $ sudo chown -R root:docker /var/lib/docker $ sudo chmod -R ug+rw /var/lib/docker/ $ sudo usermod -aG docker louis  

Website says no...

After taking that hurdle I changed directory to my existing code base and started the Lando init script $ lando init ? What recipe do you want to use? (Use arrow keys) ❯ custom backdrop drupal6 drupal7 drupal8 joomla laravel (Move up and down to reveal more choices) and chose for 'drupal8'. In the next screen I entered 'web' as webroot and 'Nagtegaal blog backend' as name. The result of this was a .lando.yml file with the following content: name: nagtegaal-blog-backend recipe: drupal8 config:    webroot: web Because I think it is essential to be able to debug an application when developing I changed this to name: nagtegaal-blog-backend recipe: drupal8 config:   webroot: web   xdebug: true which is all that is necessary to enable debugging with an ide like PHPStorm. Then I started up the application $ lando start landoproxyhyperion5000gandalfedition_proxy_1 is up-to-date nagtegaalblogbackend_database_1 is up-to-date Recreating nagtegaalblogbackend_appserver_1 ... done Waiting until appserver service is ready (...) BOOMSHAKALAKA!!! Your app has started up correctly. Here are some vitals: NAME nagtegaalblogbackend LOCATION /home/louis/Sources/nagtegaalblog SERVICES appserver, database APPSERVER URLS   https://localhost:32785   http://localhost:32786   http://nagtegaalblogbackend.lndo.site:8000   https://nagtegaalblogbackend.lndo.site   Because this was an existing project I had a database dump ready and imported it $ lando db-import dbname.sql But please note: Database dump must be located inside app-directory, but you do not want database dumps in your git repo (no, you really don't!) so make sure *.sql and *.sql.gz files are added tot the .gitignore. Then full of expectations I opened the website at http://localhost:32786 and got:
The website encountered an unexpected error. Please try again later.
Oké, so that was a nice experience! In my old setup first thing I did when encountering a situation like this was to look in the Apache log files to check what caused the error. After some searching I found that you could also do something like this in Lando with $ lando logs -t -f database_1 | 2018-07-30T09:45:01.376174060Z 2018-07-30T09:45:01.375655Z 2610 [Note] Access denied for user 'xxdrupal8'@'nagtegaalblogbackend_appserver_1.nagtegaalblogbackend_defaul' (using password: YES) appserver_1 | 2018-07-30T09:45:01.377229272Z [Mon Jul 30 09:45:01.377098 2018] [php7:notice] [pid 287] [client 172.18.0.1:48056] Drupal\\Core\\Database\\DatabaseAccessDeniedException: SQLSTATE[HY000] [1045] (...) Which, of course, means that I did not provide the correct username / password for the database. Because this was an existing project which I had running locally in my old setup, I already had a settings.php file with the "correct" username and database in my Drupal sites. Obviously this were the wrong credentials but what are the correct ones. Luckily, Lando comes with an info command that provides all the necessary information $ lando info {   "appserver":   {   "type": "php",   "version": "7.1",   "hostnames": [   "appserver",   "appserver.nagtegaalblogbackend.internal" ],  "via": "apache",  "webroot": "web",  "config": {  "conf": "/home/louis/.lando/services/config/drupal8/php.ini" },  "urls": [   "https://localhost:32785",   "http://localhost:32786",   "http://nagtegaalblogbackend.lndo.site:8000",   "https://nagtegaalblogbackend.lndo.site"  ] }, "database": {  "type": "mysql",  "version": "5.7",  "hostnames": [   "database",   "database.nagtegaalblogbackend.internal"  ],  "creds": {    "user": "drupal8",   "password": "drupal8",   "database": "drupal8"  },   "internal_connection": {   "host":   "database", "port": 3306  },  "external_connection": {    "host": "localhost",   "port": "32784"  },  "config": {    "confd": "/home/louis/.lando/services/config/drupal8/mysql" },   "urls": [] } The information I was looking for was "database": {   (...)   "creds": {     "user": "drupal8",     "password": "drupal8",     "database": "drupal8" },   and after changing the credentials in the settings.php file I finally got a working website.

Drupal says yes...

Since the site is running inside a docker container you \can not use commands like 'drush', however Lando makes using drush very easy, just prepend any drush command wiht 'lando': $ lando drush sql-cli $ lando drush uli $ lando drush cr // And of course the Drupal console is also present $ lando drupal // To login to mysql $ lando mysql etc...

But, wait a minute!

Of course the above is a wonderful story and a clear example of the power of open source and communities, but it is not what we set out to achieve. What we wanted is a local environment equal to that of our servers, but what we got is a standard Lando setup with Apache, PHP 7.1 and MySQL 5.7. So how to get the versions we want? One of the reasons I really like Lando is because this is very simple. In the .lando.yml you can override the default versions of the recipe by adding entries for the correct versions. Just add them to the config section like this name: nagtegaal-blog-backend recipe: drupal8 config:   webroot: web   # Determine webserver   via: nginx   # Activate xdebug   xdebug: true   # PHP version   php: '7.2'   # Database version   # - `mysql`   # - `mariadb`   # - `postgres`   database: mariadb:10.1 See the documentation for more information and examples. After restart the application with $ lando rebuild ? Are you sure you want to rebuild? Yes

Ahh, lovely!

   
Author