Docker allows you to create lightweight and portable containers that encapsulate any application. Your app and its runtime environment are packaged together. Starting your app requires only Docker and your container.
Docker installation is simple, but takes a non-trivial amount of time to complete. Baking Docker into your machine image has the desired effect of minimizing provisioning time, but image creation is typically a hassle.
Enter Packer. Packer simplifies the creation of machine images for EC2, Digital Ocean, Vagrant, and many other virtual environments. By defining a basic Packer template, creating Docker-capable images can be done with a single command.
Here is our Packer template:
We take a base Ubuntu 12.04 LTS image and install Docker on it (as per the official guide) using the script defined in provisioners. Other provisioners are supported: you could swap the shell script out for (or append) Chef, Ansible, or another supported provisioner.
This template will create an EC2 AMI. To create other images, simply replace/append the builder with one for another provider.
Note we specify the Docker version in a variable. Variables can be used throughout the template with {{user `var_name`}}.
Before we build our image on EC2, we'll need to export our AWS credentials as environment variables:
To kick off the build, we invoke packer build:
For EC2, you can copy the AMI to other regions using the AWS Console or awscli:
Typical build times are ~5-15min, but this could be improved by using a newer release of Ubuntu. (Docker requires a newer kernel than is shipped with Ubuntu 12.04). Cross-region copy times are quick, typically under a minute.
With your new AMI, you should now be able to provision Docker hosts in just a minute or two.