Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New provider: Docker #3347

Merged
merged 17 commits into from
Apr 10, 2014
Merged

New provider: Docker #3347

merged 17 commits into from
Apr 10, 2014

Conversation

fgrehm
Copy link
Contributor

@fgrehm fgrehm commented Mar 28, 2014

This is the code from the docker-provider project, updated to work with Vagrant 1.5 new features and with support for Docker 0.9+ only.

Here's what I installed on my Ubuntu 13.10 machine:

$ docker info
Containers: 2
Images: 131
Storage Driver: aufs
 Root Dir: /home/fabio/docker/aufs
 Dirs: 135
Execution Driver: native-0.1
Kernel Version: 3.11.0-18-generic
WARNING: No swap limit support

$ docker version
Client version: 0.9.1
Go version (client): go1.2.1
Git commit (client): 3600720
Server version: 0.9.1
Git commit (server): 3600720
Go version (server): go1.2.1
Last stable version: 0.9.1

Here are the relevant sections from docker-provider README for future documentation and ideas for what do to next.


Features

  • Support for Vagrant's up, destroy, halt, reload and ssh commands
  • Port forwarding
  • Synced / shared folders support
  • Set container hostnames from Vagrantfiles
  • Provision Docker containers with any built-in Vagrant provisioner (as long as the container has a SSH server running)

Initial setup

The plugin requires Docker's executable to be available on current user's PATH and that the current user has been added to the docker group since we are not using sudo when interacting with Docker's CLI. For more information on setting this up please check this page.

vagrant up

On its current state, the plugin is not "user friendly" and won't provide any kind of feedback about the process of downloading Docker images, so before you add a docker-provider base box it is recommended that you docker pull the associated base box images prior to spinning up docker-provider containers (otherwise you'll be staring at a blinking cursor without any progress information for a while).

docker pull fgrehm/vagrant-ubuntu:precise
bundle exec vagrant box add precise64 http://bit.ly/vagrant-docker-precise
bundle exec vagrant init precise64
bundle exec vagrant up --provider=docker

Under the hood, that base box will configure docker-provider to use the fgrehm/vagrant-ubuntu:precise image that approximates a standard Vagrant box (vagrant user, default SSH key, etc.) and you should be good to go.

Using custom images

If you want to use a custom Docker image without creating a Vagrant base box, you can use a "dummy" box and configure things from your Vagrantfile like in vagrant-digitalocean or vagrant-aws:

Vagrant.configure("2") do |config|
  config.vm.box = "dummy"
  config.vm.box_url = "http://bit.ly/vagrant-docker-dummy"
  config.vm.provider :docker do |docker|
    docker.image = "your/image:tag"
  end
end

Configuration

This provider exposes a few provider-specific configuration options that are passed on to docker run under the hood when the container is being created:

  • image - Docker image to run (required)
  • privileged - Give extended privileges to the container (defaults to false)
  • cmd - An array of strings that makes up for the command to run the container (defaults to what has been set on your Dockerfile as CMD or ENTRYPOINT)
  • ports - An array of strings that makes up for the mapped network ports
  • volumes - An array of strings that makes up for the data volumes used by the container

These can be set like typical provider-specific configuration:

Vagrant.configure("2") do |config|
  # ... other stuff

  config.vm.provider :docker do |docker|
    docker.image      = 'fgrehm/vagrant-ubuntu-dind:precise'
    docker.privileged = true
    docker.cmd        = ['/dind', '/sbin/init']

    docker.ports   << '1234:22'
    docker.volumes << '/var/lib/docker'
  end
end

Networks

Networking features in the form of config.vm.network are not supported with docker-provider apart from forwarded ports. If any of :private_network or :public_network are specified, Vagrant won't emit a warning.

The same applies to changes on forwarded ports after the container has been created, Vagrant won't emit a warning to let you know that the ports specified on your Vagrantfile differs from what has been passed on to docker run when creating the container.

At some point the plugin will emit warnings on the scenarios described above, but not on its current state. Pull Requests are encouraged ;)

Synced Folders

There is support for synced folders on the form of Docker volumes but as with forwarded ports, you won't be able to change them after the container has been created. NFS synced folders are also supported (as long as you set the privileged config to true so that docker-provider can mount it on the guest container) and are capable of being reconfigured between vagrant reloads (different from Docker volumes).

This is good enough for all built-in Vagrant provisioners (shell, chef, and puppet) to work!

At some point the plugin will emit warnings when the configured Vagrantfile synced folders / volumes differs from the ones used upon the container creation, but not on its current state. Pull Requests are encouraged ;)

Box format

The box format is basically just the required metadata.json file along with a Vagrantfile that does default settings for the provider-specific configuration for this provider.

Available base boxes

LINK DESCRIPTION
http://bit.ly/vagrant-docker-precise Ubuntu 12.04 Precise x86_64 with Puppet and Chef preinstalled and configured to run /sbin/init
http://bit.ly/vagrant-docker-precise-dind Ubuntu 12.04 Precise x86_64 based on the box above and ready to run DinD

Limitations

As explained on the networks and synced folder sections above, there are some "gotchas" when using the plugin that you need to have in mind before you start to pull your hair out.

For instance, forwarded ports, synced folders and containers' hostnames will not be reconfigured on vagrant reloads if they have changed and the plugin will not give you any kind of warning or message. As an example, if you change your Puppet manifests / Chef cookbooks paths (which are shared / synced folders under the hood), you'll need to start from scratch (unless you make them NFS shared folders). This is due to a limitation in Docker itself as we can't change those parameters
after the container has been created.

@fgrehm
Copy link
Contributor Author

fgrehm commented Mar 28, 2014

Oh, and here's the Vagrantfile I've been trying things out:

# Force the provider so we don't have to type in --provider=docker all the time
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "dummy"
  config.vm.box_url = "http://bit.ly/vagrant-docker-dummy"
  config.vm.provider :docker do |docker|
    docker.image = 'fgrehm/vagrant-ubuntu:precise'
  end

  config.vm.define :vm1 do |node|
    node.vm.network "forwarded_port", guest: 80, host: 8080
    node.vm.provider :docker do |docker|
      docker.privileged = true
    end

    node.vm.synced_folder '.', '/vagrant', id: 'vagrant-root',
                          type: :nfs,
                          mount_options:['rw', 'vers=3', 'tcp', 'nolock']
  end
  config.vm.define :vm2

  config.vm.provision :shell, inline: 'apt-get update && apt-get install -y nginx && sudo service nginx start'
end

@thasmo
Copy link

thasmo commented Mar 28, 2014

This only runs on UNIX-like hosts, right?

@fgrehm
Copy link
Contributor Author

fgrehm commented Mar 28, 2014

Yup!

@martin-watkins
Copy link

awesome!
with docker vagrant becomes even more powerful 👍

@mitchellh
Copy link
Contributor

@fgrehm Sorry I rebased vagrant-next against master, can you rebase your changes?

@fgrehm
Copy link
Contributor Author

fgrehm commented Apr 6, 2014

@mitchellh done!

@mitchellh
Copy link
Contributor

Awesome. Let's bring it in. There are quite a few things I want to polish up that I'll email you about, but this is a fantastic start.

mitchellh added a commit that referenced this pull request Apr 10, 2014
@mitchellh mitchellh merged commit 7b42fcf into vagrant-next Apr 10, 2014
@mitchellh mitchellh deleted the f-docker-provider branch April 10, 2014 02:35
@rvangundy
Copy link

Is there any documentation that describes requirements for a docker image that can be run as a provider? I would like to see an example Dockerfile that exposes ports, etc. and configures itself to be accessible and useful when run by the docker-provider.

@mitchellh
Copy link
Contributor

@rvangundy Any and all docker images

name = params.fetch(:name)
cmd = Array(params.fetch(:cmd))

run_cmd = %W(docker run --name #{name} -d)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to create a docker machine with a static IP address --- would it require patching this create method?

@ghost ghost locked and limited conversation to collaborators Apr 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants