ENVYfile Reference

Detailed guide to ENVyfile syntax and contents.

Anatomy of an Envyfile

This is an overview of what an Envyfile can look like. Hover over the underlined text to see an explanation of the line

environment:
  base:
    image: ruby:stretchThe Docker image to use as a base for this environment
  system-packages:List of APT packages to be installed in the environment
    - recipe: python3.7APT package name
      version: 3.7.1-1~18.04APT package version
    - recipe: docker
  setup-steps:Additional setup steps not included in APT packages
    - name: bundleThe name of the script
      label: "Installing Ruby Dependencies"The step label that will be displayed when envy runs this step
      run:Commands to run to complete this step
        - "bundle install"A command passed to the Bash shell - can contain Bash special characters.
      triggers:List of things that can cause this step to be run (in addition to the first envy up)
        files:Files that are watched for changes and should cause this step to run
          - GemfileA Ruby gemfile, specifying Ruby packages to be installed
          - Gemfile.lock
  x-forward: TrueEnable X-forwarding for the project. Optional, defaults to False.
actions:Actions are scripts or commands contributors are likely to use often
  - name: lintThe name of the command, used to invoke it
    script: 'rubocop'The Bash invocation to be run upon invoking the command
    help: 'lint the project'The help text displayed when envy --help is used
  - name: run
    script: 'ruby hello.rb'
    help: 'run the project'
  - name: bundle
    script: 'bundle'
    help: 'run bundler'
services:
  compose-file: docker-compose.ymlAn _optional_ docker-compose file, started and stopped with the ENVy environment
network:The docker network configuration for envy. Specificy "host" to use docker's host networking (not fully implemented on Docker for Mac), or provide a dictionary with the options below
  name: my-docker-networkThe name of a specific docker network for the envy container to run on. Usually only useful in conjuction with a docker-compose file
  ports: The list of ports to map from the environment to your host network. Useful for accessing web servers and similar that are run inside envy.
    - 43
    - 80:8080


Environment

The Environment object describes the development environment that will be used to work on the project. This object contains base, system-packages, and setup-steps.

base

An object (optional).

This object describes the base container. Normally, this container is barebones, with the utilities actually being used installed by the system packages and setup steps sections.

This will contain exactly one key, image, an optional string. This is the Docker image used as the starting point for the environment. (optional, default is ubuntu:18.04). Note that for the system-packages configuration to work, this image will need to support the apt package manager.

environment:
  base:
    image: ubuntu:18.10



project-dir

A string (optional)

This string describes the project directory mount path within the ENVy environment. If not specified, it defaults to /project. This can be useful for certain projects (e.g. Golang) where the project must exist and a particular path format. This path must be specified as an absolute path.

environment:
  project-dir: '/anotherDirectory'



system-packages

An array (optional)

This array contains a list of packages that will be installed on the system. Each package is specified by a recipe (mandatory), and an optional version. The recipe refers to an exact apt package name, and the version refers to a version available in the repository. The Ubuntu package repository is a good place to search for recipes and versions.

environment:
  system-packages:
    - recipe: docker
    - recipe: python3.7
      version: version: 3.7.1-1~18.04



setup-steps

An array (optional).

This array contains a list of setup steps that will be performed after packages are installed during the initial envy up, and, optionally, at points in the future when envy up is invoked.

Each step has a name (mandatory, string) to describe the step, a run (mandatory, array of strings) to list the commands that must be run to complete the step, and some have triggers (optional, object) defined.

Ideally, setup steps are written in such a way that they are idempotent, and as such can be run multiple times without causing changes (or at least without causing damage) to the development environment. This allows for more flexibility when deciding on when to trigger setup steps.

Note that by default, steps are run with the same UID/GID as the user invoking ENVy. This helps avoid mangling file permissions in your repository. If this causes setup steps to fail, add the as_user: false flag to your setup step.

Triggers

Triggers require some more in-depth explanation. Sometimes, it makes sense to run setup steps again after the initial envy up. This can be simple, such as an updated package.json file causing npm install to be re-run, or more complex, like triggering every time a specific other step has been run. Many projects do not require triggers at all.

Note that triggers do not set up ‘watches’ on files or conditions specified - steps will only ever be run when envy up is called

There are three types of Triggers:

  • system-packages: Run this step any time one of the listed system packages has updated or been reinstalled. Useful for reinstalling non-native packages that are likely to depend on native packages, like Python modules.
  • files: Run this step any time one of the listed files within the project directory has changed. Useful for reinstalling non-native dependencies, with tools like pip or npm.
  • steps: Run this step any time of of the named steps are run. This can be useful for finalizing installation of another step, or to create dependency chains of steps.
  • always: Run this step every time envy up is run.
environment:
  setup-steps:
    - name 'Seed sqlite database'
      as_user: false
      run:
        - 'sqlite3 maindata.db < create.sql'
    - name: 'install npm packages'
      run:
        - 'npm install --dev'
      triggers:
        files:
          - package.json



Actions

Actions are common tasks for contributors to run. This often includes tasks such as linting, running tests, building a release artifact, or simply running the application itself. This section allows maintainers to pre-define the commands contributors are likely to need.

Actions are invokable by using their name directly after envy on the command line - so an action called “lint” is invoked by running envy lint.

Users can see the available actions in a project by running envy --help anywhere in the project directory.

All actions, by default, are run from the current working directory. If this is not desirable, then set the disable_relpath option for the action.

Actions contain three required fields:

  • name (mandatory, string) that contributors can call this action using
  • script (mandatory, string) the command passed to Bash (can contain Bash special characters like pipes or ampersands) that executes this action.
  • help (mandatory, string) the help text presented to users when they run envy --help

as well as one optional field:

  • disable_relpath (mandatory, boolean) to disable the default behaviour of scripts being run from the current working directory. If this is set to true, then all scripts will start from the project root.
actions:
  - name: lint
    script: 'rubocop'
    help: 'lint the project'
  - name: run
    script: 'ruby hello.rb'
    help: 'run the project'



Services

Many projects need accompanying services to run at the same time in order to have a complete development environment. ENVy supports this through the concept of services (sometimes called “sidecar services”). These are started at the same time envy up is run, and stopped when envy down or envy nuke is run.

At the moment, only docker-compose based service files are supported. Please open an issue if you’d like to see more.

You can specify the docker-compose file you’d like ENVy to manage state for using the compose-file key:

services:
  compose-file: docker-compose.yml



</div>

Network

Envy is intended to operate transparently inside its own environment. However, sometimes it is necessary to be able to interact with services from the envy environment, or access the environment from your host machine. ENVy supports this through network configuration.

By default, ENVy’s underlying docker container uses an arbitrarily assigned network, making it difficult to connect to or from the environment. By specificying a network type of host ENVy will use docker’s host networking to make the experience closer to running directly:

network: "host"

Unfortunately, this feature is not fully implemented within Docker for Mac, so if the project is expected to be developed on Mac then host networking must be used with caution.

ENVy can also support picking the docker network to communicate on, as well as expose ports to the host by providing named keys to the network key instead of a string:

network:
  name: docker-network-name
  ports:
    - 443
    - 80:8080