Using Docker with Vagrant

Development environments can often be mixed, using both virtual machines and Docker containers. While virtual machines include everything needed to run a full operating system like memory, CPU, a kernel and all required libraries, a container is much more lightweight and can share all this with its host, while keeping a good isolation through special kernel features named cgroups. Docker containers helps developers use, share and ship a bundle including everything needed to run their application. Here, we'll show how to use Vagrant to start containers. Since Docker usage is a little different between Linux hosts and other platforms, the reference used here is the native Docker platform—Linux.

Getting ready

To step through this recipe, you will need the following:

  • A working Vagrant installation (no hypervisor needed)
  • A working Docker installation and basic Docker knowledge
  • An Internet connection

How to do it…

We'll see how to use, access, and manipulate an NGINX container in Vagrant using Docker as a provider.

Using NGINX Docker container through Vagrant

Let's start with the simplest Vagrantfile possible, using the nginx:stable container with the Docker Vagrant provider:

Vagrant.configure("2") do |config|
  config.vm.hostname = "vagrant-docker-1"
  config.vm.post_up_message = "HTTP access: http://localhost/"
  config.vm.provider "docker" do |docker|
      docker.image = "nginx:stable"
  end
end

Simply start it up with the following code:

$ vagrant up --provider=docker
Bringing machine 'default' up with 'docker' provider...
==> default: Creating the container...
[…]
==> default: HTTP access: http://localhost/

Let's remove the need to specify the provider on the command line by setting a simple Ruby environment access code at the top of the Vagrantfile:

ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'

Now you can distribute your Vagrantfile and not worry about people forgetting to explicitly specify the Docker provider.

Exposing Docker ports in Vagrant

Okay, the previous example wasn't terribly useful as we didn't expose any ports. Let's tell Vagrant to expose the Docker container HTTP (TCP/80) port to our host's HTTP (TCP/80) port:

  config.vm.provider "docker" do |docker|
      docker.image = "nginx:stable"
      docker.ports = ['80:80']
  end

Restart the Vagrant and verify you can access your NGINX container:

$ curl http://localhost/

Sharing folders with Docker through Vagrant

What about sharing a local folder so you can code on your laptop and see the result processed by the Vagrant environment? The default NGINX configuration reads files from /usr/share/nginx/html. Let's put our own index.html in there.

Create a simple src/index.html file, containing some text:

$ mkdir src; echo "<h1>Hello from Docker via Vagrant<h1>" > src/index.html

Add the Docker volume configuration to our Docker provider block in Vagrant:

  config.vm.provider "docker" do |docker|
      docker.image = "nginx:stable"
      docker.ports = ['80:80']
      docker.volumes = ["#{Dir.pwd}/src:/usr/share/nginx/html"]
  end

Note

#{Dir.pwd} is the Ruby for finding the current directory, so you don't hardcode paths, making it highly distributable.

Restart the Vagrant environment and see the result:

$ curl http://localhost
<h1>Hello from Docker via Vagrant<h1>

Note

On SELinux-enabled systems you may need to do some configuration that's beyond the scope of this book. We encourage you to secure your Docker systems using SELinux, but to disable SELinux just type the following:

$ sudo setenforce 0

There's more…

You can choose not to use your local or default Docker installation, but instead use a dedicated VM, maybe to reflect production or a specific OS (such as CoreOS). In this case, you can specify a dedicated Vagrantfile as follows:

config.vm.provider "docker" do |docker|
docker.vagrant_vagrantfile = "docker_host/Vagrantfile"
end
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.137.38