Smooth and simple Docker image development with Ansible. Small configuration changes result in quick incremental updates of development images.
To build an image from scratch:
dockerflow build .
To rebuild the image incrementally after changing a playbook or file:
dockerflow rebuild .
To drop into a shell inside the container when the build fails so you can figure out what happened interactively:
dockerflow debug-build .
Existing Docker build systems don't support my preferred development workflow, which has four actions:
- build: Build an image from a base image and a configuration spec.
- rebuild: Make a change to the configuration spec; efficiently build an incremental update of the current build.
- debug-build: Attempt to build an image from the base image and configuration spec, but drop into a shell inside the container on failure so I can identify the problem interactively.
- debug-rebuild: Like debug-build, but with rebuild.
Why not Dockerfiles?
Dockerfiles are fine for 'build', but can be inefficient for 'rebuild'. Consider the following Dockerfile:
RUN apt-get install x y z
RUN long-running-source-build
...
If you remember that the subsequent steps also require apt-get install w
, you can either add w
to the existing apt-get install line, which means you have to wait for your long-running source build to finish again; or add a second apt-get install
line further down, which gets confusing.
Also, I like Ansible's declarative approach to configuration better than Dockerfiles' imperative one.
If you also like Ansible but care about sticking with Dockerfiles more than 'rebuild', check this out.
Why not Packer?
I don't want the output to be complete tarballs of images, but tagged Docker images that I can push. Also, I want an easy incremental option.
Install Node.js, then sudo npm install -g dockerflow
.
dockerflow action path [options]
, where action can be build, rebuild, debug-build or debug-rebuild.
In more or less the spirit of Dockerfiles, the given path should contain an Ansible playbook called 'dockerflow.yml' which specifies the configuration. In addition, the given path will be available inside the container read-only at /dockerflow
during the build, but will not be bundled into the image.
The playbook should define the following variables:
- dockerflow-base: The id or tag of the image from which the build should start.
- dockerflow-tag: The tag that will be applied to the output image.
- dockerflow-docker-options (optional): An arbitrary string of options to pass to the Docker client.
- dockerflow-environment (optional): A space-separated list of environmental variables to forward into the container. You can access environmental from playbooks using this method or this method.
- dockerflow-command: A command for the image to run automatically on startup.
Alternatively, these options can be set using command line options --base
, --tag
, --docker-options
, --environment
and --command
. Command line options override config file options. Note that if you override --base
, there is no difference between the build and rebuild actions.
If your Docker daemon is running on a nonstandard socket, you can pass the -H
or --host
argument.