Box Features

Box is a utility for the building of docker images. Through use of mruby, we provide additional flexibility over the vanilla docker build command by adding control structures and basic predicates. We also add new verbs that allow new actions, such as flattening and tagging images.

Some features that differentiate it from docker build:

Getting Box

Download a Release


Quick Install: curl -sSL | sudo bash

Or download a release: Just gunzip the downloaded file and put it in your path:

$ gunzip box.$(uname -s).gz
$ chmod 755 box.$(uname -s)
$ sudo mv box.$(uname -s) /usr/local/bin/box

Alternatively, we have a homebrew tap and debian and redhat packages on the releases page.

Build Plans

Build Plans power Box and are the core of its functionality. This document describes how you can power box by writing build plans, and what techniques to use while writing them.

Box Build Plans are Programs

Exploit this! Use functions! Set variables and constants!

run this plan with:

GOLANG_VERSION=1.7.5 box [plan file]

If a plan name is not specified it will default to box.rb.

from "ubuntu"

# this function will create a new layer running the command inside the
# function, installing the required package.
def install_package(pkg)
  run "apt-get install '#{pkg}' -y"

run "apt-get update"
install_package "curl" # `run "apt-get install curl -y"`

# get the local environment's setting for GOLANG_VERSION, and set it here:
go_version = getenv("GOLANG_VERSION")
run %Q[curl -sSL \{go_version}.linux-amd64.tar.gz \
    | tar -xvz -C /usr/local]

Powered by mruby

Box uses the mruby programming language. It does this to get a solid language syntax, functions, variables and more. However, it is not a fully featured Ruby such as MRI and contains almost zero standard library functionality, allowing for only the basic types, and no I/O operations outside of the box DSL are permitted.

You can however:

Tagging and Image Editing

You can tag images mid-plan to create multiple images, each subsets (or supersets, depending on how you look at it) of each other.

Additionally, you can use functions like after, skip, and flatten to manipulate images in ways you may not have considered:

from :ubuntu
skip do
  run "apt-get update"
  run "apt-get install curl -y"
  run "curl -sSL -O"
  tag :downloaded

run "dpkg -i box*.deb"
after do
  tag :installed

Because the tag is processed after the final edits occur, tag installed will not contain the update manifests, curl, or the .deb. Tag downloaded will, though (but will also not contain the installed package).

The Debugger

debug is a really powerful tool for establishing a breakpoint in your build plan where you can investigate your container.

Just add a line:


And as soon as it is reached you will see a shell appear in your console.

Verb Properties

copy, run, and other support properties to modify their behavior. You should check out what you can do in the docs, but here are a few examples.

# `output: false` runs vim without attaching to the TTY, allowing you to run this
# command in a logging environment as well as a terminal one
run "vim +PluginInstall -c 'set nomore' +qall", output: false

# `ignore_list` takes an array of string patterns to ignore from the
# file list.
copy "*", ".", ignore_list: %w[foo bar]

Experiment with the REPL

The REPL is a line interpreter that immediately gives you feedback on any given statement, allowing you to build an image interactively.

Works great with debug!

Launch with box repl.

Parallel Building

box multi can build several plans at once. Just supply multiple filenames!

Note that multi-builds do not return the output of run statements, largely because there would be a lot of noise in parallel execution.