Lando has an advanced plugin system that allows developers to add and extend Lando's core functionality. Here are a few examples of things you can do with plugins:

  1. Create CLI commands like lando danceparty
  2. Add services like solr, redis or ruby
  3. Add additional configuration options and functionality to .lando.yml
  4. Hook into various Lando runtime events to provide additional functionality.
  5. Print "A British tar is a soaring soul!" after every app is started.

Plugin Basics

Plugins give you access to the Lando API so that you can modify and/or extend Lando. Here is the main entrypoint of the engine plugin that adds the lando.engine module and handles engine config.

'use strict';

const _ = require('lodash');
const env = require('./lib/env.js');
const ip = require('ip');
const path = require('path');

// Helper for default config
const getDefaultConf = (env, lando) => ({
  composeBin: env.getComposeExecutable(),
  composeVersion: '3.2',
  containerGlobalEnv: {},
  dockerBin: env.getDockerExecutable(),
  dockerBinDir: env.getDockerBinPath(),
  engineId: lando.user.getUid(),
  engineGid: lando.user.getGid(),
  engineScriptsDir: path.join(lando.config.userConfRoot, 'engine', 'scripts'),

// Helper to get default env
const getDefaultEnv = config => ({
  LANDO_ENGINE_CONF: config.userConfRoot,
  LANDO_ENGINE_ID: config.engineId,
  LANDO_ENGINE_GID: config.engineGid,
  LANDO_ENGINE_HOME: config.home,
  LANDO_ENGINE_REMOTE_IP: (process.platform === 'linux') ? ip.address() : 'host.docker.internal',
  LANDO_ENGINE_SCRIPTS_DIR: config.engineScriptsDir,

module.exports = lando => {
  // Add some config for the engine'post-bootstrap', 1, lando => {'Configuring engine plugin');
    // Merge user opts over the defaults, this allows users to set their own things
    lando.config = lando.utils.config.merge(getDefaultConf(env, lando), lando.config);
    // Strip all DOCKER_ and COMPOSE_ envvars
    lando.config.env = lando.utils.config.stripEnv('DOCKER_');
    lando.config.env = lando.utils.config.stripEnv('COMPOSE_');
    // Set up the default engine config if needed
    lando.config.engineConfig = env.getEngineConfig(lando.config);
    // Set the ENV
    _.forEach(getDefaultEnv(lando.config), (value, key) => {
      lando.config.env[key] = value;
    // Add some docker compose protection on windows
    if (process.platform === 'win32') lando.config.env.COMPOSE_CONVERT_WINDOWS_PATHS = 1;
    // Log it
    lando.log.verbose('Engine plugin configured with %j', lando.config);
    // Add utilities
    lando.utils.engine = require('./lib/utils');
    // Move our scripts over and set useful ENV we can use
    lando.log.verbose('Copying config from %s to %s', path.join(__dirname, 'scripts'), lando.config.engineScriptsDir);
    lando.utils.engine.moveConfig(path.join(__dirname, 'scripts'), lando.config.engineScriptsDir);

  // Add some config for the engine'post-bootstrap', 2, lando => {'Initializing engine plugin');
    lando.engine = require('./engine')(lando);

Running your own plugins

You can add plugins either globally or in individual apps by adding your plugin to the global config.yml or an individual app's .lando.yml.

  - my-plugin

In the above example Lando looks for a plugin in a folder called my-plugin in either the node_modules or plugins folders. For app plugins these locations will be relative to the app root directory. For global plugins the locations specified in pluginDirs in lando config will be scanned.

If there are multiple occurences of the same-named plugin, Lando will use the one "closest to your app". This means that lando will priortize in-app plugins and then priortize the locations in pluginDirs from last to first.

A powerful corollary to this is that indiviual apps can implement plugins that override global plugin behavior.

Where is config.yml?

Check out the global config docs if you are unclear where to change this file.

Plugin Examples

Check out some of our core plugins for motivation in creating your own.

results matching ""

    No results matching ""