This is a communicator plugin allowing vagrant to access docker instances as if they have SSH.
This was created to facilitate host file management using a vagrant host file manager plugin, which requires SSH to fetch, edit, and put back container hosts files. The assumption that vagrant SSH communicator makes, is that all containers have SSH - They do not.
This communicator will make vagrant tasks that require SSH, interact with the docker instances, as if SSH exists, by using the Docker API.
Shell scripts used during provisioning will also be executed, so will facilitate provisioning shel scripts as well (from 1.0.8). Please note that these will always run as root inside the docker instance.
This has only been used in a Linux environment.
vagrant plugin install docker-api
Needs to be installed as a vagrant plugin
vagrant plugin install vagrant-communicator-docker
vagrant plugin install vagrant-communicator-docker-[version].gem
vagrant plugin install docker-api
(must be version 2.0.0 or greater)has_ssh
vm.communicator = 'docker'
vm.communicator.bash_shell
vm.communicator.bash_wait
Example vagrant definition:
config.vm.define "database", primary: false do |database|
database.hostmanager.aliases = [ "database."+dev_domain ]
database.vm.network :private_network, ip: "172.20.0.208", subnet: "172.20.0.0/16"
database.vm.hostname = "database"
database.communicator.bash_shell = '/bin/sh'
database.communicator.bash_wait = 30
database.vm.communicator = 'docker'
database.vm.provider 'docker' do |d|
d.image = "mysql:5.7"
d.has_ssh = true
d.name = "database"
d.remains_running = true
end
end
By default the communicator connects with Docker over a local socket. You can override this, and allow remote Docker connection by setting an environment variable:
DOCKER_HOST=tcp://[DOCKER HOST]:[PORT]
example:
DOCKER_HOST=tcp://127.0.0.1:2375
vagrant up
The default shell will be /bin/bash inside the docker container. You can override this using : vm.communicator.bash_shell = '/bin/sh';
to use /bin/sh (or any other shell)
If you get the error:
The guest operating system of the machine could not be detected!
Vagrant requires this knowledge to perform specific tasks such
as mounting shared folders and configuring networks. Please add
the ability to detect this guest operating system to Vagrant
by creating a plugin or reporting a bug.
you likely need to change the shell to /bin/sh OR increase the shell_wait (default is 10)
OR the docker image in use (example: debian:bullseye) is not staying active after created.
You can force that by passing -t
as a docker create arg in the vagrant setup
Vagrant.configure("2") do |config|
config.vm.define "test-case", primary: false do |d|
d.vm.communicator = 'docker'
d.vm.provider 'docker' do |box|
box.image = "debian:bullseye"
box.has_ssh = true
box.remains_running = true
box.create_args = ["-t"]
end
end
end
it would seem box.remains_running = true
don't work on all docker images !
I have found some docker instances need a little extra time to initialise, before docker can send commands The default wait timeout is 10s. Increase in increments of 5 to see if you can overcome issue.
Not had this for some time, so I think solved due to ongoing changes.
I have not managed to spend time on this, to pin it down, but some (random) docker images will fail if you set d.has_ssh = true
- The only fix is to set that to false, which can stop other functions (example usage of a hostmanager plugin)
You can run a global trigger to overcome this, allowing hostmanagers to update after it was completed:
config.trigger.after :up do |trigger|
trigger.run = {inline: "bash -c 'vagrant hostmanager --provider docker'"}
end
vagrant halt database && vagrant up database --debug &>/tmp/debug.log
then view the debug log.
You will see debug entries with the string: DOCKER COMMUNICATOR
Bug reports and pull requests are welcome on GitHub at https://github.com/ProxiBlue/vagrant-communicator-docker.
The gem is available as open source under the terms of the MIT License.