Lando is ready for the masses with RC2 release
Holla!!! We are super pumped to announce the release of Lando 3.0.0-rc.2!.
About midway through 2018 we reached a few of the milestones we were looking for:
- Over 5,000 monthly active users
- Breaking more things than we were fixing on each release
- High levels of technical debt
- More support requests than we could handle
While the amount of monthly active users and support requests were very surprising (and encouraging) to us the other two were not because SPOILER ALERT: our
beta releases were essentially proof of concepts; prototypes hacked together to demonstrate whether people actually wanted something like Lando or not. Our conclusion from this data was that not only do the people want something like Lando but they crave it.
Since then we've been listening to users and heeding their advice as we try to lock down the core set of Lando's functionality and figure out what we needed to do to take Lando to the next level. This has been a very enlightening process, aided by the lessons learned during the Kalabox project and culminating in this release.
At time of writing Lando has peaked very close to 9,000 monthly active users and has averaged around 8,000 for the last quarter or so.
We never dreamed we'd have this many users before a stable release and have been working very hard to cut a release that lays the foundation for more growth and adoption in the future.
Speaking of new foundations we'd like to tell you all what we've done to prep Lando for a stable release and beyond...
Reducing Techincal Debt
Hitherto, and as mentioned above, Lando has been essentially a prototype. We've been haphazardly pushing up new code while leaving no thought for the morrow as we try to confirm the features users need to be successful developing their projects. That process, while important and illuminating, resulted in a massive amount of techincal debt.
Lando RC2 is in many ways a bottom-up rewrite to address this problem; to consolidate code around an emergent set of community-agreed-upon features.
Believe it or not the technical debt ratio at the beginning of 2018 was actually around 60%!.
While this reduction has been much needed we've implemented CI tests to make sure no new code introduced into Lando increases its technical debt beyond an unacceptable threshold.
Locking Down the API
Refactoring the code to reduce technical debt and getting a better sense of the core features means we can now also provide better docs and API stability. To that end you can now read our lips when we say no new breaking changes.
This means that RC2, while still not a stable release, will not be changing its core syntax and will guarantee backwards compatibility here on out.
You can take the following docs to the bank.
- SSH Keys
- Shared Files
- Global Config
We've put in a ton of effort to document and test the above so there is a considerable amount of inertia required to substantially change any of them. This means that you can count on our laziness for future stability.
While reducing techincal debt was important to make things simpler, more stable, more mangeable and more maintainable, good testing was equally critical to identify regressions and ensure that things remain simple, stable, manageable and maintainable.
To that end we've implemented both unit and functional tests.
We don't have 100% coverage yet but we are covering the most important things.
We wrote our own functional testing framework called leia to help us do functional testing. Leia helps us ensure that Lando is the real hero we all know him to be. Leia uses
markdown files and
bash commands to do functional testing.
Here is a sample screenshot of one part of one test we run on one of the 10 concurrent CircleCI machines that run on every build.
This means that you should be able to
git clone the examples folder and succesfully run any of them. If you are interested in checking what these tests look like on CircleCI you can go here.
So what did we change?
While a consequence of RC2 has been some annoying breaking changes we've prepared an update guide to help you update your Landofiles.
Breaking changes aside, here are all the awesome improvements in RC2.
We've rebased a lot of our images on Bitnami's because they are more "local dev" ready. This has provided a bunch of extra stability.
A downside of this is that some supported Lando versions have gone away.
Build steps can now run before and after your application starts. That means you can now install node dependencies or install php extensions before your application starts up.
Install node deps before app starts
services: node: type: node:10 build: - yarn
Install a php extension and then composer install
services: appserver: type: php:7.1 build_as_root: - apt-get update -y && apt-get install -y libmemcached-dev - pecl install memcached - docker-php-ext-enable memcached build: - composer install
Tooling is more powerful than ever.
Native command emulation
One of the most common uses of tooling is to emulate native commands like
tooling: php: service: appserver
The above will run
php inside of the
appserver and also pass in any additional args or options you specify. That means that you can run
lando php in the exact same way as
php. This greatly reduces the hassle involved in invoking said commands directly with
docker-compose or even
lando ssh. See below:
# OMG WHYYYYY docker exec -it mysite_appserver_1 /bin/sh -c "/path/to/my/php -e \"phpinfo();\"" # Hmm ok that's a bit better lando ssh -c "php -e \"phpinfo();\"" # Oh so nice! lando php -e "phpinfo();"
Consolidated command tooling
You may also wish to consolidate a complex command into a simpler one. This is useful because it can help prevent human error and reduce documentation.
tooling: update-deps: service: database description: Updates the installed packages on my database service cmd: apt update -y && apt install -y user: root
cmd can also be an array. This allows you to chain an indefinite amount of commands together.
tooling: fire-everything: service: node description: Runs a seemingly random assortment of commands cmd: - source ~/.bashrc - npm install "$DEP_SET_BY_ENVVAR_SOURCED_BEFORE" - /helpers/my-custom-script.sh --max-power - ls -lsa - env | grep LANDO_
Note that each line of the above runs in a separate subshell so if you
source a file in the first command like we unwisely did above it's not going to be available in any of the others. If you need that sort of behavior consider something like this instead
tooling: fire-everything: service: node description: Runs a seemingly random assortment of commands cmd: - source ~/.bashrc && npm install "$DEP_SET_BY_ENVVAR_SOURCED_BEFORE" - /helpers/my-custom-script.sh --max-power - ls -lsa - env | grep LANDO_
Multi-service Multi-command tooling
You can also omit the
service and define
cmd as an array of objects where the
key is the service and the
value is the command. This can allow you to consolidate complex testing and build steps that need to happen across many different services.
It also allows you to reuse a common interface across many different Landofiles, eg
lando test may differ from project to project but it's always what we use to run our tests.
tooling: build: description: Manually invokes all our build steps cmd: - appserver: composer install - node: yarn install - node: yarn sass test: description: Run ALL THE TESTS cmd: - appserver: composer test - node: yarn test
lando test && lando build
Dynamic service commands
Sometimes you have, need, or want a single command that can be used on a user-specified service. In these situations you can tell Lando to set the service with an option.
Note that the
: prefix is what tells Lando to use an option instead of a literal string. Also note that you should be careful to avoid collisions between options you specify and options the underlying command does.
tooling: php-version: service: :service cmd: php -v options: service: default: appserver describe: Run php in different service
# Get the version in the appserver lando php-version # Get the version in the second appserver lando php-version --service appserver2 # Get the version in the third appserver lando php-version --service appserver3
This can help avoid the following messy and hard-to-scale implementation
tooling: php-version: service: appserver cmd: php -v php-version2: service: appserver2 cmd: php -v php-version3: service: appserver3 cmd: php -v
Options driven tooling
You can also define your own options for use in tooling. These options follow the same spec as Lando tasks and are generally used in combination with an underlying script.
Note that the options interface just provides a way to define and then inject options into a given command. It is up to the user to make sure the underlying command or script knows what to do with such options. Note that if you use interactive options you need to set
level: app as below.
tooling: word: service: web cmd: /app/word.sh level: app options: word: passthrough: true alias: - w describe: Print what the word is interactive: type: input message: What is the word? default: bird weight: 600
# This will prompt for the word lando word # This will not lando word --word=fox
We've also improved how tooling commands are escaped so you can now also do things like this
lando php -e "phpinfo();" lando terminus remote:drush "$SITE.$ENV" -- cr --all -y lando mysql -e "show variables;"
You can now use pre and post Landofiles to set base and overrides configurations. You can do the following things:
If you are developing a project start state or have a set of Lando configurations you'd like to ship with all your projects you can use a "base" file with defaults that can then be overriden by your usual
.lando.yml. By default Lando will detect any of the following files automatically and load them before your
.lando.base.yml .lando.dist.yml .lando.upstream.yml
On the flip side you might have some user-specific configuration you'd like to use on only your computer. For these situations Lando similarly offers an "override" file that will be loaded AFTER all base files and your
.lando.yml. Generally you will want to
.gitignore this file.
Restart vs. Rebuild
If you change your Landofiles you now need to explicitly run
lando rebuild instead of running
lando restart. This helps to provide stability between restarts until you explicitly ask for things to change and vastly speeds up stops and starts.
lando rebuild -y
We've completely reworked
lando init to be more modular and intuitive. This means if you've got scripts relying on
lando init you will likely need to make some changes. While there are many changes the biggest are the removal of the "init method" in favor of the
lando init pantheon
lando init --source pantheon
There is no longer a register of apps stored at
~/.lando/cache/registry. As a consequence you can no longer do things like
lando start MYAPP
lando start MYAPP
cd /path/to/MYAPP lando start
You now have to explicitly set the top level
env_file if you want to load a
.env file in Lando root directory
env_file: - .env
We've vastly simplified our Drush handling. You can now only set
drush to a particular version for global installation. If you've installed
composer then Lando will use that version instead of the one in your Landofile.
recipe: drupal8 config: drush: none
recipe: drupal8 config: drush: composer
recipe: drupal8 config: drush: /path/to/my/drush
recipe: drupal8 config: drush: 8.1.15
Lando no longer uses
-- to differentiate between its options and tooling options.
# Verbose modes lando start -- -v lando start -- -vv lando start -- -vvv lando start -- -vvvv # Lando help lando start -- --help
# Verbose modes lando start -v lando start -vv lando start -vvv lando start -vvvv # Lando help lando start --lando
A nice consequence of this is you can now use
-- in other tooling commands and have more predictable tooling results
# Use -- in a command lando terminus remote:drush "$SITE.$ENV" -- cr --all -y # Worry less about escaping crap lando php -e "phpinfo();"
If you have written your own custom plugins
- Sorry!! :/
- Once you see the new format you'll feel better :)
We've finally locked down a Plugin System that uses the Lando and App APIs and while we still don't have a great way to manage the installation and management of these plugins, it is going to be the defining feature of
Here is the complete list of changes in RC2.
- Added a
inquirer-autocomplete-promptto select inquirer prompts #1017
- Added configurable support for
.lando.*.ymlsource files eg
- Added support for
- Added support for multiple, user-defined
envfiles #994 #1045 #1265 #1242
- Added support for
pcntlextension to all PHP images #910
leiato help keep
landothe real hero we all know he is #1296
- Added a better message if users arrive at an "impossible" place #1158
rebuildevents to fire on the outside #1352
sshkey loading to also load passphrase protected keys by default #1288 #1143 #808
- Changed default
xdebug: falseto actually disable the
- Changed update warning to print to
wordpressrecipe to download
1.5.1if using php 5.3 #1334
- Changed PHP to have unlimited memory for CLI ops #732
postgresconfig loading preventing outside connections #1379
- Fixed busted auto-naming on Windows deploy #1375
- Fixed busted
drushglobal-local handoff on Pantheon #1375
- Fixed regression in
LANDO_INFOcausing services to be index values instead of names #1376
- Fixed regression causing databases to report as unhealthy after a restart #1381
- Fixed tooling on Windows to not always run as root #1362
- Fixed annoying recoverable php error
Cannot set 'user' save handler by ini_set()on php 7.2 #747
- Fixed bug where files
rsynced from Pantheon were being set to
750#1325 #1067 #1330
- Fixed longstanding permissions bug with legacy
- Fixed bug where not-owned-by-me
.sshconfig was blowing up
sshkey loading #1203
- Fixed bug causing
postgresservices to intermittently crash on
- Fixed regression in
eventscaused by "multi word" tooling eg
- Fixed regression in
lando logs --service SERVICEnot actually filtering #1386
- Fixed long-standing race condition causing build fail perimission errors on
linux#1227 #1197 #1170
- Fixed bug where
docker-composefiles were not loading correctly outside of the app root #1007
- Fixed bug where
nodeservices were not getting the
- Fixed bug where cyclical
app -> appsymlink was being create in
- Fixed various
solrconfig bugs #1249 #1350 #1319 #1351
- Increased events
- Improved tooling is-service-already-running delegation #1378
drushhandling, fixes #1315 #1317 #1318
sshkey loading to use the
LANDO_HOST_USERby default #1082
- Improved handling when an unknown service is used with the
lando"global options", fixes #1173
How do I update to use all the magix in RC2?