Tooling

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 composer or 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 php or 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:

  1. Consolidating multiple commands on multiple services into a singular lando SOMETHING command. This is great for complex build steps, testing and deployment.
  2. Easily surface options and arguments that can be passed from Lando into a script running in your container.
  3. Run the same command on different services using a flag of your choosing.

Make sure to install your dependencies

You will want to make sure you install the tools you need inside of the services your app is running. If you are not clear on how to do this, check out either build steps or our ssh command.

Example

# 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

Caveats

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.

Overriding

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"

Disabling

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

Directory Mapping

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.

Tool Discovery

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.

results matching ""

    No results matching ""