Introducing Docker in Vagrant

[EDIT: Since this post was written, OrbStack has appeared. It’s really good for running Docker containers and VMs on a Mac. You should check it out instead.]

If you’re a Mac user, you have a few options for running Docker. Aside from Docker’s official client, there also exists Rancher Desktop and Podman. I’ve used them all, and they’re all decent implementations of Docker. However, I ran into some limitations in each platform that are beyond the scope of this post that nonetheless prompted me to try building out my own Docker offering.

Having used VirtualBox and Vagrant before, I found myself wondering if I could use Vagrant to stand up an instance of Docker, proxy connections to Docker over SSH, and mount directories on the host machine’s filesystem.

It turns out I could.

Features

So let me tell you about some of the features that my app, Docker in Vagrant has:

  • Aliases and scripts for all operations. No need to run Vagrant directly!
  • Packages that are installed on the VM via yum will be cached to disk outside of theVM, making future builds less network intensive.
  • With a single command, Docker images can be saved outside of the VM and reloaded if a new VM is stood up.
  • I even figured out how to keep the VM’s clock in sync with the host machine!

Getting Started

In addition to VirtualBox and Vagrant, you’ll also need to have the Docker CLI Tools and Pipe Viewer installed. Once those are all installed, you can clone the repo! After the repo is cloned, run the script ./bin/start.sh to start the VM. The script will then print out some additional configuration instructions, which I will summarize here:

  • echo "export DOCKER_HOST=ssh://vagrant@127.0.0.1:2222" >> $HOME/.bashrc
    • This will tell Docker to talk to the VM when issuing Docker commands.
  • echo . $(pwd)/bin/docker-aliases-bash.sh >> $HOME/.bashrc
    • This will set aliases that can be used to interact with the VM running Docker

Finally, add this into $HOME/.ssh/config so that you can connect to the VM via SSH:

Host 127.0.0.1
     ControlMaster auto
     ControlPath ~/.ssh/master-%r@%h:%p
     ControlPersist yes
     StrictHostKeyChecking no
     UserKnownHostsFile /dev/null
     IdentityFile $(pwd)/.vagrant/machines/default/virtualbox/private_key
     IdentitiesOnly yes

At this point, you’re good to go! Just start a new shell so the environment variable and aliases are set up, first. 🙂

Usage

All Docker commands should Just Work. But you can start by running docker ps, followed by docker run hello-world. In addition to the Docker commands that you know and love, there are a number of aliases that can be used to manage the underlying VM:

  • docker-status – Check to see if the VM exists and if it is running.
  • docker-start – Start the VM if it is stopped.
  • docker-stop – Stop a running VM.
  • docker-restart – Restart a running VM.
  • docker-destroy – Destroy a VM. It can be recreated with docker-start.
  • docker-ssh – SSH into a VM if you need to do any troubleshooting in there.
  • docker-images-save – Export all existing images from the VM to the host filesystem. Use before running docker-destroy.
  • docker-images-list – List all images that have been exported from the VM.
  • docker-images-load – Load all images from disk into the VM. Used after creating a new VM.
  • docker-check-time-offset – Check the time on the host versus the VM. Run docker-restart in the highly unlikely event that they’ve fallen out of sync.
  • docker-aliases – Print these aliases. 🙂

Conclusion

I have been successfully using Docker In Vagrant for my own development for a few months now, and I am overall pleased with the functionality and performance that it offers. If you’re looking for something new in the Docker ecosystem, why not give it a try?

Mirror on Medium.