Docker Introduction
Why use Docker?
There has been plenty written elsewhere about Docker in general and the choice of Docker against other tools like Vagrant, Ansible, etc. In short, Docker allows running of containers that provide specific environments and dependencies required to run an application, either in production or in a simple to manage development environment. These containers are generally lightweight, composable, and disposable. This keeps the host system (perhaps your laptop) isolated and clean by not locally installing all kinds of dependencies needed for specific projects or just when trying something new. The dependencies are installed and ran inside the disposable container instead.
Here I’ve made some notes on a quick introduction to Docker by using a container to run Jekyll, which is the tool that generates this site. See more at the Docker docs.
Installing Docker CE
Follow the Ubuntu installation instructions.
Be sure to add your user to docker
group to avoid requiring sudo
. It is
probably safer not to run containers as root unless necessary.
sudo adduser `whoami` docker
Run Jekyll in a Docker container
Simply run:
docker run --rm --label=jekyll --volume=$(pwd):/srv/jekyll \
-it -p 127.0.0.1:4000:4000 jekyll/jekyll \
jekyll server --drafts
This will download and run the official Jekyll docker image with all dependencies running at or very close to the same versions as used on Github pages. This means it is only necessary to have Docker installed locally but not Ruby or any other dependencies.
To break this command down a little:
--rm
removes the container once the command exits--label=jekyll
gives the container a nice label. I’m not quite sure where this label is used. It seems the--name=jekyll
option would be more useful as thename
is usable in place of<container-id>
in commands likestart
andstop
.--volume=$(pwd):/srv/jekyll
shares the current directory with the Docker container located at/srv/jekyll
within the container-it
is shorthand for--interactive
and--tty
-p 127.0.0.1:4000:4000
defines a port mapping to expose port 4000 inside the container to port 4000 on the host. This ensures we can accesslocalhost:4000
in a browser and access the jekyll server running inside the containerjekyll/jekyll
is the name of the docker image on which the container is basedjekyll server --drafts
is the command that is run inside the container to run the jekyll server with drafts published
The --rm
option could be left of to preserve the container after jekyll is
stopped. You could then restart jekyll without having to wait for the container
to rebuild by running
docker start <container-id>
with the container ID that is shown for the jekyll container in docker ps
-a
. This would run the container but you would not see any output. To see
output from a running container, you can run docker attach <container-id>
. You
can start the container and attach automatically by using the -a
option. You
could stop the container by running docker stop <container-id>
. All pretty
simple stuff.
If you did not provide the --rm
option, the container can be removed when you
are done with it via docker rm <container-id>
. Once the image has been
downloaded, the container comes up pretty quickly even if the --rm
option is
used. The main difference in this particular case is that the ruby gems will
have to be reinstalled when fresh containers are used.
Docker Compose
The docker run
command is kind of long and inconvenient to type every time you
want to work on a jekyll site. Docker Compose can be used to
simplify this so the single command docker-compose up
will create or start the
container as defined by a docker-compose.yml
file, and run the jekyll server
so everything is ready to work on the site.
The docker-compose.yml
file for the jekyll container looks something like
this:
jekyll:
image: jekyll/jekyll:pages
command: jekyll server --drafts
ports:
- 4000:4000
volumes:
- .:/srv/jekyll