Presenting with Docker
A few people have asked me about my presentation environment recently. I present about 30-40 times a year and I’ve got my process (still not funny apparently) and tooling pretty much down pat.
For my content, I’ve long been a fan of Hakim El Hattab’s Reveal.JS. Reveal.JS is a presentation framework that allows you to create awesome slideshows that can be displayed via your browser via a builtin web server.
You can specify slides in HTML or Markdown.
|
|
I’ve recently combined this with Wetty, a terminal in the browser that allows me to have in slide SSH. No longer do I need to switch between my terminal and my slides whilst demo’ing. I find that’s pretty bloody cool (and people love it). I sometimes have as many people ask me how I do the “secret in browser terminal magic” than I do about the topic of my presentation.
{:.center}
One of the annoying aspects of using both tools is that they do get updated fairly regularly and installation is still basic and via git clone
. This means I need to keep them up to date to fix minor issues. It also means I end up with a checkout of both tools inside each repository that I store my presentations in, like my Introduction to Docker talk.
So I decided that I’d make my life easier by creating a Docker image for my presentation stack. I designed it so that the data (my content) would be separated from the code (the presentation stack). Each presentation repository contains the following files:
|
|
The slides/slides.html
file holds my slides and the images
directory holds any images I am using in my slides.
I then have a Docker image that holds my presentation stack. Here’s the Dockerfile
for my image.
|
|
The Dockerfile
is pretty self-explanatory. I base the image on Ubuntu 14.04 (to get the latest NodeJS). I install NodeJS, NPM, and Git. I then install Reveal.JS, its dependencies and Grunt to power it.
By default Grunt only binds the Reveal.JS server to localhost
so I edit the Gruntfile.js
to update the server. This will bind Grunt to all interfaces so I can expose my presentation on the container’s external network interface.
I also add Wetty and its dependencies.
I then add some template content and images I use and a Docker CSS theme to render my slides using Docker’s colors and styles.
Finally I set my working directory to the presentation directory, expose port 8000 and specify a command to run, grunt serve
, when a container is launched from this image. So when a container is launched Grunt will serve out my presentation on port 8000, which I can then directly map 1:1 or on a port in Docker’s default port range.
I can then build my image (I actually use a Trusted Build but I could also build from the command line):
|
|
Then launch a container from my image!
|
|
This creates a container called docker_presentation
and mounts /Users/james/src/intro-to-docker/images
and /Users/james/src/intro-to-docker/slides
into the container. I would update these paths for the specific presentation I am loading. The container is launched daemonized and port 8000 inside the container is mapped to port 8000 outside on the host.
If I now browse to http://localhost:8000
I will see my Introduction to Docker presentation.
If I wanted to launch another presentation I could create a new container like so:
|
|
I’ve updated my volume mounts to the new presentation and I am now mapping the port to one of Docker’s ports. This allows me to run more than one presentation locally rather being restricted to port 8000. Let’s see which port got assigned with the docker port
command.
|
|
If I now browse to http://localhost:49159
I will see my Ops Mythology presentation.
Now I don’t need to worry about anything in my presentation stack or worse duplicate its code in every presentation. Now all I need to do is maintain my content and my images and I am done!
You can find the code for this here and the Docker image is available on Docker.io here.