Lando provides a way to easily define nice
lando MYCOMMAND commands so that users can take advantage of development tools that are installed inside of containers. Setting up some common routes for things like
npm allows the user to get a "native" experience but perhaps more importantly allows project specific development dependencies to be isolated and run in containers instead of on the user's host machine. You never need to worry about which version of
grunt you need for each project.
You can think of tooling configuration as a nice way to alias a superset of commands that would otherwise need to be run as something like
lando ssh -c "composer install".
The many ways you can configure tooling are in the example below but here are some of the more powerful use cases:
- Consolidating multiple commands on multiple services into a singular
lando SOMETHINGcommand. This is great for complex build steps, testing and deployment.
- Easily surface options and arguments that can be passed from Lando into a script running in your container.
- Run the same command on different services using a flag of your choosing.
Make sure to install your dependencies
# Tooling example name: trivial-tooling # Proxy the basics proxy: nginx: - trivial-tooling.lndo.site # Let up a basic LEMP stack services: appserver: type: php:7.1 via: nginx webroot: www # Run composer install after we start our app run: - "cd $LANDO_MOUNT && composer install" # Add in a helper script to showcase some magic below overrides: services: volumes: - $LANDO_APP_ROOT_BIND/word.sh:/helpers/word.sh cli: type: node:6.10 database: type: mariadb portforward: true # This section defines our tooling routes tooling: # Define `lando composer` as a command that runs `composer --ansi @` against # the appserver service. Note that @ will be any additional arguments you pass # into `lando composer` # # Example: typing `lando composer install` will run `composer --ansi install` # inside the container. composer: # Run the `lando composer` command against the appserver from the services # section above service: appserver # Give a nice description to describe what this does. # If ommited this will default to "Run COMMAND commands" where COMMAND is # composer in this case description: Run composer commands # Define a specific command to start with inside the container. If ommited # this will default to the name you give the service eg composer. # # This can be a string or an array if you want to run multiple commands # See "test" below for a multi-command example cmd: composer --ansi # Define `lando php` as a command that runs `php @` against the appserver where # @ is additional input from the user. php: # Run this command against the appserver service: appserver # Run this command as the www-data inside of the container. If ommitted this # will default to the LANDO_WEBROOT_USER envvar for the service and then root # if undefiend. You can also pass in user:group. # # Note that the user needs to already exist inside of the container user: www-data # Define `lando mysql` as a command that will drop the user into a mysql shell # inside of the database service mysql: service: database description: Drop into a MySQL shell user: root # Define a tooling command with a stringed command test: # Run multiple commands on the same service service: appserver cmd: - echo "we expect the next command to fail" - composer test description: Run all the tests # Define `lando word` that passes through to a script that can handle options. # The script is mounted into our appserver in the service overrides above # # This script doesnt really do anything it's just to demonstrate options declaration # for the lando cli eg if you run `lando word -- --help` you should see some # options. # # Note that you can also specify options for the commands above as well but # generally it makes more sense to just delegate to the options of the command # you are invoking itself # # Note that options get passed into commands no matter what and AS IS. They do # not need to be defined explicitly here. This is purely to provide helpers # when running `lando CMD -- --help` or to get interactive prompts. As an # example try running `lando word -w bird --surprise`. `--surprise` is not defined below but # has a handler in our word.sh. word: service: appserver cmd: /helpers/word.sh options: word: # If you are specifying interactive options, as is the case here, # you will want to set passthrough to true so that interactive answers # get translated into command line args for the script to handle passthrough: true alias: - w describe: Print what the word is interactive: type: input message: What is the word? default: bird weight: 600 # Define `lando npm` so that it also requires the `database` service to be running # in order to work. # # This is useful for complex commands that can act on multiple services eg # a database-import, or drush status check, or pull from a hosting provider # like pantheon npm: service: cli # Add a string or array of services that also need to load up for this # command to function properly needs: - database # Define `lando dynamic` so that it can run on different services based on # the `--service` flag instead of a hardcoded option # # This is useful for complex commands that can act on multiple services eg # a database-import, or drush status check, or pull from a hosting provider # like pantheon dynamic: # Just print the hostname so we know what service we are on cmd: printenv LANDO_SERVICE_NAME # The format :NAME will use the service specified by the NAME flag # You likely will want to specify the option below and set a reasonable # default service: :service # Specify a service option to handle the above options: service: default: appserver alias: - s describe: Run a different service # Define `lando install` so that it can run on different services on the command # values # # This is useful for complex build steps that need to run on multiple containers, # note that the usual "service" key will only be used as the fallback value for the # service with the key of the command taken precendent. install: # Run our two build steps cmd: - appserver: composer install - cli: yarn install description: Install everything
You can see the extra commands by running
lando inside your app.
lando Usage: lando <command> [args] [options] [-- global options] Commands: config Display the lando configuration destroy [appname] Destroy app in current directory or [appname] info [appname] Prints info about app in current directory or [appname] init <appname> [method] Initializes a lando app called <appname> with optional [method] list List all lando apps logs [appname] Get logs for in current directory or [appname] poweroff Spin down all lando related containers rebuild [appname] Rebuilds app in current directory or [appname] restart [appname] Restarts app in current directory or [appname] ssh [appname] [service] SSH into [service] in current app directory or [appname] start [appname] Start app in current directory or [appname] stop [appname] Stops app in current directory or [appname] version Display the lando version composer Run composer commands php Run php commands mysql Drop into a MySQL shell Global Options: --help, -h Show help --verbose, -v, -vv, -vvv, -vvvv Change verbosity of output You need at least one command before moving on
There are some current caveats with Lando tooling with which you should be familiar
- Using pipes | or carrots < > can be strange because data needs to be streamed across the host-container boundary. In these situations we recommend you use
lando ssh -c "mycommand < myfile"or set up on explicit tooling command to keep things entirely inside the container.
You can override tooling provided by Lando by redefining the tooling options in your
.lando.yml file. For example, if you wanted to override the built in
drush command that comes with Drupaly recipes so that it always runs in a specific directory you could do the below.
tooling: drush: cmd: "drush --root=/app/web"
You can also disable built in tooling by setting the command to a non-object value in your
.lando.yml file. While any value will do it's convention to use
disabled as in the below.
tooling: push: disabled
Lando will try to map your host directory to the analogous directory inside the service. This should MAKE IT SEEM as though you are running the command locally eg not in a container.
If you are not sure about what tools live inside your container, you can use
lando ssh to drop into a shell on a specific service to both investigate and install any needed dependencies.
# SSH into the appserver lando ssh appserver # Explore whether grunt is installed which grunt # not installed # Add grunt npm install -g grunt-cli # Exit the appserver container exit # Add grunt to the tooling in your .lando.yml
While you can do the above, it's generally recommended to install any additional dependencies as part of the build process either using specific dependency management built into the service you are using or with Lando's more generic build step process.