Migrating from Vagrant to Docker - Part 1
I have a new computer and well, the new computer does not run vagrant, well, it really doesn’t run virtual box, it does run docker. I have decided it’s time to go with docker for my virtualization needs.
I go over key commands in managing a vagrant system in my workflow: creating, running, and connecting into a guest operating system - and the docker equivalent.
If you are looking to migrate your workflow from vagrant to docker, you will gain a smoother path by knowing what vagrant commands map to docker commands to get the same things done.
This article will take you about five minutes to read.
Introduction
I enjoy working with a virtualbox when developing with vagrant managing the system configuration for me. The system is in a consistent state and
I am so comfortable in vagrant that if I want to get into docker more, I need the “docker equivalent for this vagrant command”.
The docker commands are around the base docker commands (i.e. docker
(build | images | run | ps | exec)
). Docker has additional tooling which I
will explore deeper in the future.
This article will focus on the commands to get the current version of Ubuntu on vagrant and docker.
This article, part 1, will cover:
- files for configuration
- command to start system
- command to login
Let’s get started!
Selecting Guest Operating System
With virtualized systems, one can run a different operating system than the current system, known as “guest” and “host”, respectively. Think: of a host providing resources for a guest to run.
How vagrant and docker specify which guest operating system is similar through specific configuration files.
Vagrantfile
The most basic Vagrantfile
to have vagrant create a system using the
current version Ubuntu as of this writing, it is: Focal Fossa would
be:
Vagrant.configure('2') do |config|
config.vm.box = 'ubuntu/focal64'
end
Making this into one line is possible.
More Guest Operating Systems
If you want to find more operating systems, checkout vagrant boxes.
Dockerfile
The most basic Dockerfile
that docker would accept to setup a system
with Ubuntu Focal Fossal is:
FROM ubuntu:focal
CMD ["sleep", "1d"]
Why is line CMD ["sleep", "1d"]
in the file? This line is optional
as all it does is have the system sleep
(for five days at that!)
This is one area where vagrant and docker differ philosophically.
From using it, vagrant, it is configuring a full blown guest system for usage within the host system. Remember, vagrant is an abstraction ontop of VirtualBox, which its core design goal is to emulate a computer inside a computer. (Vagrant just makes managing that computer easier.)
Docker core design goal is creating small “software appliances” that does one thing and one thing only (which I find ironic with software.)
Without the last line, CMD ["sleep", "1d"]
, the system would start
and immediately shutdown, because the system finished all the
commands. The sleep
command here would keep the system up, for a
day.
More Guest Operating Systems
For more guest operating systems in docker, checkout Docker Hub.
Creating System
Both vagrant and docker have simple ways to create the specified system from their respective configuration files.
vagrant
One would just have to run:
vagrant up
within the same folder as the Vagrantfile
.
Vagrant creates all the associated files with it. Moving the
Vagrantfile
would create a new system, even with no file changes.
docker
The simplest command would be:
docker build .
which does work, I would suggest adding a <tag name>
, such as:
ubuntu
or focal
or ubuntu_focal
or anything else.
docker build . -t <tag name specified by you>
To see what has been built, run: docker images
:
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 0fbb6d52aaba 33 hours ago 65.6MB
ubuntu_focal latest 325acabf7223 33 hours ago 65.6MB
There are two images, one tagged: ubuntu_focal
and the other
without. Note, both are essentially Ubuntu Focal with slightly
different build options.
docker and images
Docker designed to create lots of images and without tagged names, one
would have only SHA and time to remember what image corresponds to
which Dockerfile
Docker has a central repository for the images for the
Dockerfile
. Moving the Dockerfile
will not create new system if
there are no file changes.
Running System
After creating a system, getting a system running is the next step. This means starting the guest operating system within the host operating system, using up resources.
vagrant
This is where vagrant is convenient where the same command that
creates the system vagrant up
would also start the system.
docker
The command to running a system in docker created from the previous step is:
docker run <tag/SHA>
The <tag/image ID>
refers to the listing output from docker
images
:
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 0fbb6d52aaba 33 hours ago 65.6MB
ubuntu_focal latest 325acabf7223 33 hours ago 65.6MB
When the image has a tag, that’s sufficient:
docker run ubuntu_focal
If only the Image ID is available:
docker run 0fbb
With those tag names and image IDs, the above commands are equivalent.
Logging In
The main use case I have virtualized software such as vagrant or docker is to run stuff inside those systems instead of on the host system. Logging into those systems with an interactive prompt is essential and simple.
vagrant
The command to login to a running system managed by vagrant:
vagrant ssh
vagrant has configured the virtual computer behind the scene with special SSH keys. It’s almost magical how simple working with a vagrant system is.
docker
Connecting to an interactive prompt on a docker system is a bit different as the design goal of docker is to have a software appliance.
Connecting to a running docker system will take:
- finding the container ID of the system
- running the
docker exec
command
docker ps
To find running containers, run: docker ps
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
98b09714e4d8 ubuntu_focal "sleep 5d" 16 seconds ago Up 15 seconds suspicious_wescoff
The container ID here is: 98b0
OR suspcious_wescoff
- you can use
either to address the container in the docker exec
command.
docker exec
The docker exec
command is to execute a command in a running
container. To get an interactive shell in a container:
docker exec -it <container ID/name> /bin/bash
Can I do Better?
There is a shortcut, if you only want to ever connect to the same container, use command:
docker ps | grep <tag> | awk '{ print $1 }'
To get the container ID of the image you want. Combine that with the previous command into:
docker exec -it $(docker ps | grep <tag> | awk '{ print $1 }') /bin/bash
This command is familiar :-)
Command Summary (so far)
Current summary of all the commands, side by side:
vagrant | docker | |
---|---|---|
selecting guest operating system | see Vagrantfile section | see Dockerfile section |
creating the system | vagrant up |
docker build . -t <tag name> |
running the system | vagrant up |
docker run <tag> |
connecting into the system | vagrant ssh |
docker exec -it <container SHA> /bin/bash |
Conclusion
A quick summary of different commands to migrate from managing virtual machines in vagrant to docker. Commands such as:
- connecting into a system
- running the system
- creating it
- selecting which guest operating system to run
I’m looking forward to sharing more as I migrate from having vagrant as the center of my workflow to docker.