Reputation: 467
I would like to have a Docker container running Redis, inside a Vagrant VM. I'd like things to be as simple as they can possibly be, so minimal configuration.
A little bit of research shows:
So the setup should be really straight forward, I expected to just have to connect the dots. So I came up with this Vagrantfile
:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "chef/centos-6.5"
config.vm.provision "docker" do |docker|
docker.run "dockerfile/redis"
end
end
Looks simple - good. Now when I run vagrant up
I would expect:
dockerd
is started.dockerfile/redis
is downloaded and installed.All seems to work except step 3, since with this Vagrantfile
I get:
==> default: Verifying vmnet devices are healthy...
==> default: Preparing network adapters...
==> default: Starting the VMware VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 192.168.249.190:22
default: SSH username: vagrant
default: SSH auth method: private key
default: Warning: Connection refused. Retrying...
==> default: Machine booted and ready!
==> default: Forwarding ports...
default: -- 22 => 2222
==> default: Configuring network adapters within the VM...
==> default: Waiting for HGFS kernel module to load...
==> default: Enabling and configuring shared folders...
default: -- /Users/ernst/nikon/nikon-elk-vm2: /vagrant
==> default: Running provisioner: docker...
default: Installing Docker (latest) onto machine...
default: Configuring Docker to autostart containers...
==> default: Starting Docker containers...
==> default: -- Container: dockerfile/redis
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
rm -f /var/lib/vagrant/cids/cc3cfcdebad9167099d85261c6311a0011838655
docker run --cidfile=/var/lib/vagrant/cids/cc3cfcdebad9167099d85261c6311a0011838655 -d --name dockerfile-redis dockerfile/redis
Stdout from the command:
Stderr from the command:
2014/11/26 12:38:40 Cannot connect to the Docker daemon. Is 'docker -d' running on this host?
I could obviously revert to using the shell
provisioner, but I would love to keep my Vagrantfile
simple and use the docker
provisioner that Vagrant offers.
So what am I missing?
Upvotes: 4
Views: 3501
Reputation: 2106
I think you confused provider and provisioner. Provisioner offer an environment for configuring the VM. In case of Docker that means you can add containers to the docker-host which so to say "configures" the VM in some way. Other provisioners are "Shell", "Chef" or "Puppet". Providers are tools to spawn VM's or in this case containers. Other Providers are for example "VirtualBox" or "AWS".
Here's some code which may help you get started:
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'
Vagrant.configure(2) do |config|
config.vm.define "docker-host", autostart: false do |host|
host.vm.hostname = "docker-host"
host.vm.box = "chef/centos-6.6"
# The following line terminates all ssh connections. Therefore
# Vagrant will be forced to reconnect.
# That's a workaround to have the docker command in the PATH
host.vm.provision "shell", inline: "ps aux | grep 'sshd:' | awk '{print $2}' | xargs kill"
host.vm.provision "docker"
end
host.vm.define 'container', primary: true do |ws|
ws.vm.hostname = 'container'
ws.vm.provider "docker" do |d|
d.image = "library/redis:latest"
d.vagrant_machine = "dev-host"
d.vagrant_vagrantfile = "./Vagrantfile"
d.force_host_vm = true
end
end
end
Output:
$ vagrant up container
Bringing machine 'container' up with 'docker' provider...
==> container: Docker host is required. One will be created if necessary...
container: Vagrant will now create or start a local VM to act as the Docker
container: host. You'll see the output of the `vagrant up` for this VM below.
container:
container: Importing base box 'chef/centos-6.6'...
container: Matching MAC address for NAT networking...
container: Checking if box 'chef/centos-6.6' is up to date...
container: Setting the name of the VM: dev-host
container: Clearing any previously set network interfaces...
container: Preparing network interfaces based on configuration...
container: Adapter 1: nat
container: Forwarding ports...
container: 22 => 2222 (adapter 1)
container: Running 'pre-boot' VM customizations...
container: Booting VM...
container: Waiting for machine to boot. This may take a few minutes...
container: SSH address: 127.0.0.1:2222
container: SSH username: vagrant
container: SSH auth method: private key
container: Warning: Connection timeout. Retrying...
container: Warning: Connection timeout. Retrying...
container: Warning: Remote connection disconnect. Retrying...
container: Warning: Remote connection disconnect. Retrying...
container: Warning: Remote connection disconnect. Retrying...
container: Warning: Remote connection disconnect. Retrying...
container: Warning: Remote connection disconnect. Retrying...
container: Warning: Remote connection disconnect. Retrying...
container: Warning: Remote connection disconnect. Retrying...
container: Warning: Remote connection disconnect. Retrying...
container: Machine booted and ready!
container: Checking for guest additions in VM...
container: Setting hostname...
container: Mounting shared folders...
container: /vagrant => <PATH>
container: /tmp/vagrant-cache => <PATH>
container: Configuring cache buckets...
container: Running provisioner: docker...
container: Installing Docker (latest) onto machine...
container: Configuring Docker to autostart containers...
container: Configuring cache buckets...
container: Running provisioner: shell...
container: Running: inline script
container: Configuring cache buckets...
==> container: Syncing folders to the host VM...
container: Mounting shared folders...
container: /var/lib/docker/docker_1417023698_82709 => <PATH>
==> container: Warning: When using a remote Docker host, forwarded ports will NOT be
==> container: immediately available on your machine. They will still be forwarded on
==> container: the remote machine, however, so if you have a way to access the remote
==> container: machine, then you should be able to access those ports there. This is
==> container: not an error, it is only an informational message.
==> container: Creating the container...
container: Name: virtual-dev_container_1417023701
container: Image: library/redis:latest
container: Volume: /var/lib/docker/docker_1417023698_82709:/vagrant
container:
container: Container created: 2f020d26797f3bd0
==> container: Starting container...
==> container: Provisioners will not be run since container doesn't support SSH.
Usage:
Use vagrant up
to start the redis container. Since we force a host for the container vagrant will automatically start it if it's not available. You can start the host directly with vagrant up docker-host --provider=virtualbox
. After everything started you can ssh into the docker-host by using vagrant ssh docker-host
. Note that most Docker containers don't have SSH so you can't ssh them by using vagrant ssh container
. What you can do to look into the container is using the following "trick" as long as the container is running:
docker ps
copy the ID of the containerdocker exec -it <ID-of-container> /bin/bash
Additional notes:
ENV['VAGRANT_DEFAULT_PROVIDER'] - 'docker'
- Sets the default Provider. In case of Docker you don't have to type vagrant up --provider=docker
. Default is virtualbox
.
d.vagrant_vagrantfile = "./Vagrantfile"
- Sets the location of the Vagrantfile of the docker host. Thus you can have a own Vagrantfile for every container! Anyway, this example uses the multi-mechine structure [1].
You can adress docker-host
or container
by adding it to your command. For example vagrant up docker-host --provider=virtualbox
Further reading:
Upvotes: 2
Reputation: 1567
Your Vagrantfile is correct.
This seems to be an issue with the chef/centos-6.5
box.
On this box, you have to update device-mapper-libs
first.
I had success with this Vagrantfile:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "chef/centos-6.5"
config.vm.provision "shell",
inline: "yum update -y device-mapper-libs"
config.vm.provision "docker" do |docker|
docker.run "redis"
end
end
Inside the VM:
[vagrant@localhost ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d55185f859c redis:2 "/entrypoint.sh redi 10 seconds ago Up 9 seconds 6379/tcp redis
Upvotes: 2