captain is a free, open source build & deployment project written in Go and released under MIT. It has 775 GitHub stars, 48 forks and 20 open issues, and was last pushed 1 months ago. On this registry it ranks #70 of 84 tracked projects in Build & Deployment, with 5 head-to-head comparisons available.

What is captain?

Captain is an open-source command-line tool, written in Go and released under the MIT licence, that converts an existing Git workflow into Docker container images built, tested, and pushed on a per-commit basis, and it is aimed at developers and CI pipelines that want continuous delivery without writing bespoke build and release scripts.

What it is

Captain lives in the GitHub repository harbur/captain and operates at the seam between Git and Docker. A team describes its workflow in a captain.yml file placed at the root of a Git repository, and Captain reads that file to decide which Dockerfiles to compile, which images to tag, which commands to run as tests, and which images to send to a remote registry. The tool supplies sane defaults when no configuration is present, so most repositories work without any pre-configuration at all.

The concrete problem it solves is the plumbing that usually sits between a source repository and a container registry. Instead of hand-written shell scripts that call docker build, docker tag, and docker push in CI, Captain reproduces the Git commit tree inside the Docker image tags. Each build produces images tagged as latest, COMMIT_ID, and BRANCH_NAME, which means any commit or branch can be located and pulled as an image later. Git tags are propagated to container tags as well, which is what allows distribution channels such as alpha, beta, and stable to be expressed with ordinary Git tagging rather than a separate release mechanism.

Key capabilities

  • captain build compiles the Dockerfiles found in the repository; when the working tree has local changes the resulting containers are tagged only as latest, and otherwise they are tagged as latest, COMMIT_ID, and BRANCH_NAME.
  • captain test runs the test commands declared in the configuration, stops immediately when a command fails, and reports a non-zero exit status.
  • captain push sends the selected images to the remote repository, so promotion is a deliberate step rather than a side effect of building.
  • The captain.yml format supports the keys build, image, test, pre, post, and build_arg, with pre and post holding lists of commands run around the compilation of each image.
  • Dockerfiles are auto-detected by walking the current directory and all subdirectories for files named Dockerfile or Dockerfile.*; the directory containing the Dockerfile becomes the build context sent to the Docker daemon.
  • Image names are reconstructed when not set explicitly, using username over parent_dir for Dockerfile and username over parent_dir.parsed_suffix for Dockerfile.*, with the suffix lower-cased to satisfy repository naming rules.
  • Build arguments pass through the build_arg key as keyname: keyvalue pairs, for example keyname: keyvalue beneath an image entry.

Who uses it and how

  • Teams maintaining several images in a single repository, who use Dockerfile suffixes to share one build context across multiple compiled images.
  • Continuous delivery services that invoke the three commands in sequence, building on every commit and pushing only once the declared tests pass; the project's own badge setup shows Travis CI as an example of that arrangement.
  • Release engineers who map Git tags onto container tags to operate promotion channels such as alpha, beta, and stable without maintaining separate release branches.
  • Developers who pull the image for a feature branch directly, testing a branch's built artefact instead of building it locally by hand.
  • Projects that need a lookup from commit identity to immutable image tag, so that any commit in the history can be retrieved as a container.

Getting started

Installation is a single command that pipes the release install script into a shell: curl -sSL https://raw.githubusercontent.com/harbur/captain/v1.1.3/install.sh | bash. The binary lands in ~/.captain/bin, which must be added to PATH, for example with export PATH=$HOME/.captain/bin:$PATH in .bashrc or .zshrc.

How it compares

The facts name no comparable or competing tools, so Captain stands alone in this registry rather than sitting among a listed set of rivals. Its position is defined by the two systems it orchestrates, Git and Docker, and by the pipeline stage it occupies between them.

When to use it — and when not to

A self-hoster must run a Docker daemon, and must supply a registry to push to; Captain orchestrates builds and tests but does not provide the registry, the CI runner, or the test commands themselves, all of which come from the surrounding environment. Anyone who needs a hosted service rather than a CLI installed into an existing pipeline should look elsewhere, since the README describes installation into a machine's PATH and nothing more. Two weaknesses are visible in the facts: the install script is pinned to version v1.1.3, and the documentation is inconsistent about the configuration filename, using captain.yaml in the introduction and captain.yml throughout the format section, while twenty open issues remain on the repository.

project readme (upstream, from github) — read inline

Build Status Coverage Status

Introduction

Captain - Convert your Git workflow to Docker containers ready for Continuous Delivery

Define your workflow in the captain.yaml and use captain to your Continuous Delivery service to create containers for each commit, test them and push them to your registry only when tests passes.

  • Use captain build to build your Dockerfile(s) of your repository. If your repository has local changes the containers will only be tagged as latest, otherwise the containers will be tagged as latest, COMMIT_ID & BRANCH_NAME. Now your Git commit tree is reproduced in your local docker repository.
  • Use captain test to run your tests
  • Use captain push to send selected images to the remote repository

From the other side, you can now pull the feature branch you want to test, or create distribution channels (such as 'alpha', 'beta', 'stable') using git tags that are propagated to container tags.

intro

Installation

To install Captain, run:

curl -sSL https://raw.githubusercontent.com/harbur/captain/v1.1.3/install.sh | bash

You will need to add ~/.captain/bin in your PATH. E.g. in your .bashrc or .zshrc add:

export PATH=$HOME/.captain/bin:$PATH

Captain.yml Format

Captain will automatically configure itself with sane values without the need for any pre-configuration, so that it will work in most cases. When it doesn't, the captain.yml file can be used to configure it properly. This is a simple YAML file placed on the root directory of your git repository. Captain will look for it and use it to be configured.

Here is a full captain.yml example:

hello-world:
  build: Dockerfile
  image: harbur/hello-world
  pre:
    - echo "Preparing hello-world"
  post:
    - echo "Finished hello-world"
hello-world-test:
  build: Dockerfile.test
  image: harbur/hello-world-test
  pre:
    - echo "Preparing hello-world-test"
  post:
    - echo "Finished hello-world-test"
  test:
    - docker run -e NODE_ENV=TEST harbur/hello-world-test node mochaTest
    - docker run -e NODE_ENV=TEST harbur/hello-world-test node karmaTest
project-with-build-args:
  build: Dockerfile
  image: harbur/buildargs
  build_arg:
    keyname: keyvalue

image

The location of the Dockerfile to be compiled.

When auto-detecting, the image will be re-constructed by the following rules:

  • Dockerfile: username/parent_dir
  • Dockerfile.*: username/parent_dir.parsed_suffix

Where

  • username is the host's username
  • parent_dir is the Dockerfile's parent directory name
  • parsed_suffix: is the suffix of the Dockerfile parsed with the following rules:
    • Lower-cased to avoid invalid repository names (Repository names support only lowercase letters, digits and _ - . characters are allowed)
image: harbur/hello-world

build

The relative path of the Dockerfile to be used to compile the image. The Dockerfile's directory is also the build context that is sent to the Docker daemon.

When auto-detecting it will walk current directory and all subdirectories to locate Dockerfiles of the following format:

  • Dockerfile
  • Dockerfile.*

The build path will be reconstructed automatically to compile the Dockerfile. The build context will be the directory where the Dockerfile is located.

Note: If more than one Dockerfiles are needed on specific directory, suffix can be used to separate them and share the same build context.

build: Dockerfile
build: Dockerfile.custom
build: path/to/file/Dockerfile
build: path/to/file/Dockerfile.custom

test

A list of commands that are run as tests after the compilation of the specific image. If any command fail, then captain stops and reports a non-zero exit status.

test:
  - docker run -e NODE_ENV=TEST harbur/hello-world-test node mochaTest
  - docker run -e NODE_ENV=TEST harbur/hello-world-test node karmaTest

pre

A list of commands that are run as preparation before the compilation of the specific image. If any command fail, then captain stops and reports a non-zero exit status.

pre:
  - echo "Preparing compilation"

post

A list of commands that are run as post-execution after the compilation of the specific image. If any command fail, then captain stops and reports a non-zero exit status.

post:
  - echo "Reporting after compilation"

build_arg

A set of key values that are passed to docker build as --build-arg flag. For more information about build-args see here.

build_arg:
  keyname: keyvalue

CLI Commands

build

Builds the docker image(s) of your repository

It will build the docker image(s) described on captain.yml in order they appear on file

Flags:

-B, --all-branches=false: Build all branches on specific commit instead of just working branch
-f, --force=false: Force build even if image is already built

test

Runs the tests

It will execute the commands described on test section in order they appear on file

push

Pushes the images to remote registry

It will push the generated images to the remote registry

By default it pushes the 'latest' and the 'branch' docker tags.

Flags:

-B, --all-branches=false: Push all branches on specific commit instead of just working branch
-b, --branch-tags=true: Push the 'branch' docker tags
-c, --commit-tags=false: Push the 'commit' docker tags

pull

Pulls the images from remote registry

It will pull the images from the remote registry

By default it pulls the 'latest' and the 'branch' docker tags.

Flags:

-B, --all-branches=false: Pull all branches on specific commit instead of just working branch
-b, --branch-tags=true: Pull the 'branch' docker tags
-c, --commit-tags=false: Pull the 'commit' docker tags

self-update

Updates Captain to the last available version.

version

Display version

Displays the version of Captain

help

Help provides help for any command in the application.

Simply type captain help [path to command] for full details.

Global CLI Flags

-D, --debug=false: Enable debug mode
-h, --help=false: help for captain
-N, --namespace="username": Set default image namespace

Docker Tags Lifecycle

The following is the workflow of tagging Docker images according to git state.

  • If you're in non-git repository, captain will tag the built images with latest.
  • If you're in dirty-git repository, captain will tag the built images with latest.
  • If you're in pristine-git repository, captain will tag the built images with latest, commit-id, branch-name, tag-name. A maximum of one tag per commit id is supported.

Roadmap

Here are some of the features pending to be implemented:

  • Environment variables to set captain flags
  • Implementation of captain detect that outputs the generated captain.yml with auto-detected content.
  • Implementation of captain ci [travis|circle|etc.] to output configuration wrappers for each CI service
  • Configure which images are to be pushed (e.g. to exclude test images)
  • Configure which tag regex are to be pushed (e.g. to exclude development sandbox branches)

Frequently asked questions

Is captain free to use?

captain is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does captain do?

Captain - Convert your Git workflow to Docker :whale: containers

What is captain written in?

captain is primarily written in Go. Its source is publicly available at https://github.com/harbur/captain, and it has 775 GitHub stars.