Docker basics in a nutshell

I have a number of posts from my playing around with Docker so far. I’ve seen a number of posts from people asking how they should get started with Docker. There’s a number of getting started guides that will get you up and running. Try the Getting Started tutorials on the Docker site.

I’m not going to attempt to re-write my own version of other tutorials as they are good already. Instead, I’m going to distill down a few core steps as a quick reference and a quick example. If you’ve no idea what Containerization is about, this page is a good overview.

Assuming first if you’re on Mac or Windows you’ve already installed the Docker Toolbox. If not, head over here and follow the instructions.

In a nutshell:

  • images are read-only definitions used to create a container (they describe the content of a container, starting with a base image, at the very least a base Linux OS)
  • You can browse shared images at Docker Hub (or host your own hub)
  • images can be used as the starting point and extended to create other images
  • a container is an instance of an image that can start, pause, stop

Start the Quickstart Terminal.

Let’s pull an image (busybox) and start it up:

  • docker pull busybox

Now let’s run a container based on this image, run it interactively (-i) capturing the tty (-t) and execute a shell (the hex value is the id of the image):

  • docker run -it c51f86c28340 sh

On a reasonably recent machine you’ll probably see the sh prompt appear in a second or less. If you exit the shell, your container will also terminate because it’s not running anything (by exiting the shell you terminated the command you asked the container to run).

You can see currently running containers with ‘docker ps’ and list all containers included recently terminated with ‘docker ps -a’:

Let’s start it up the same container again in interactive mode: ‘docker start -i 9fd9f0402821′ :

Each time we start it up, you should notice it starts pretty quick, in 1 second or less.

Containerization vs Virtualization

If you’ve ever installed a guest OS in a virtual machine using virtualization software like VirtualBox, VMWare or Parallels, you should now be noticing a major difference between containerization and virtualization. How did that container boot so fast??!!

The difference between these two approaches is that virtualization allows sharing of the platform hardware, so multiple guest OSes can be installed on the same hardware. Containers on the other hand allow sharing of the operating system – each container shares common libraries and resources from the underlying Linux OS. Containerization solutions like Docker rely on features natively provided by Linux to achieve this. Running Docker on a non-Linux platform, like Windows or OS X requires hybrid approach running a Linux guest in a Virtual Machine – the Docker Toolbox and docker-machine takes care of this for you.

Next steps from this point would be to create your own image running some service or app in a container. If you look through some of my previous posts, hopefully these will now make more sense now we’ve covered some of the basics.

Go try it out for yourself!

Real life story – the journey from dev to prod with containers

This story on Techcrunch, ‘I want to run stateful containers too‘ rang home with me as it reads very similar to my own learning experience playing with containers so far, although at this point I haven’t had the opportunity to take a container based system into production, but he covers a lot of the same questions as I have so far. I imagine this journey and shift in thinking from monolithic systems to container based services is a common experience for everyone starting down this path.

Wildfly Swarm JAX-RS in a Docker Container deployed to IBM Bluemix

More playing with Docker. Now, where can I deploy a container ‘for real’ to the cloud? A few options:

  • AWS has EC2 Container Service (ECS). If you haven’t used AWS before you can get a year of AWS for free. If you’ve already used up your free year, then it looks like you’ll have to pay as you go for ECS
  • Google Container Engine have a $300 free offer for 60 days
  • Digital Ocean – $5/month on lowest spec plan
  • Heroku has Docker support using a Docker image of their own runtime platform, Heroku Cedar. This is an interesting approach, but sounds more attractive if you’re already planning on deploying to Heroku as your target platform
  • OpenShift Origin v3 is Docker based, but only if you’re running OpenShift Origin yourself. OpenShift Online is still their own proprietary gears and cartridges (although still an awesome PaaS that I use for a lot of my side-projects – this blog is hosted on OpenShift).

So where does IBM’s Bluemix fit in to this picture? I have to admit, until seeing IBM’s presentations at JavaOne this year about how awesome their cloud service is, I hadn’t even taken a look at what they have to offer (I think years of devolping and deploying to Websphere v5 had left me emotionally scarred). Bluemix is Cloud Foundry based, with tons of other stuff thrown in. Including support for hosting Docker containers. And, free developer accounts (when CPU and stoarage kept below a certain level) – check out the pricing calculator. Ok, so I’m in, let’s get set up.

Deployment is via the CloudFoundry CLI with the IBM Containers plugin, instructions are here. Here’s a summary:

  • Installer Docker if not already installed
  • Install CloudFoundry CLI
  • Install IBM Containers cf plugin
  • Login to Bluemix: cf login -a api.ng.bluemix.net
  • Login in IBM Containers: cf ic login (login with Bluemix credentials when prompted)

There’s a couple of options to interact with your containers and walking through the docs the first time it’s a little confusing as they list all three alternatives for each step – either with docker cli directly, with cf cli or with the ice cli.

From the Bluemix containers dashboard, when you click add custom container, the steps it gives you are using cf cli to login, and then use the Docker cli, so this is the approach I used (the ice cli seems to give me 503 Bd Gateway errors that I couldn’t get beyond, so I followed the cf and Docker steps).

There’s an interactive tutorial for using the ice utilities from here. If you’ve worked through some other online interactive tutorials then this will look familiar 🙂 (e.g. Git tutorial)

I already have my image running a JAX-RS endpoint using WildFly Swarm – let’s get it deployed to Bluemix.

I already have my image, built with:

docker build -t wildflyswarm-jaxrs

Next, we need to tag it:

docker tag wildflyswarm-jaxrs registry.ng.bluemix.net/kevinhooke/wildflyswarm-jaxrs
  • the first param is the tag name from when we built the image
  • second param is the Bluemix image repository uri, followed by your account namespace (set when you register with Bluemix), and then the tagname for your image
To push the tagged image to the Bluemix repository:
docker push registry.ng.bluemix.net/kevinhooke/wildflyswarm-jaxrs

At this point if you head over to your Bluemix Containers dahboard, you’ll see your image listed (along with some provided images from IBM):

 Using the cf cli with the IBM Containers plugin, ic), you can issue docker comands direct to Bluemix, so to list containers remotely:

cf ic images

Let’s start a container from the image!

cf ic run --name jaxrs-test registry.ng.bluemix.net/kevinhooke/wildflyswarm-jaxrs

This should return you a container id.

So is it running? Let’s pass a Docker ps using cf ic:

cf ic ps

We’re up and running! (or at least building, it hasn’t started yet)

Now how do we access the service in the container? It seems like we need to go to the online console and request a public IP for the container. The free account gives you 2 free public IPs:

From the cli, the approach is to request a public ip:

cf ic ip request

and note the returned ip.

Now start the container and pass the ip from the previous step – I’m also binding 8080 from my container to 8080 on the host to make it accessible:

cf ic run -p 134.168.10.169:8080:8080 --name jaxrs-test registry.ng.bluemix.net/kevinhooke/wildflyswarm-jaxrs

The docs say the public ip may take a few minutes before it’s available.

I don’t know how long the containers in Bluemix normally take before they transition to running, for me it seemed to take a while in the ‘networking’ status.

After waiting a few minutes and checking the console, SUCCESS, we’ve transitioned to ‘running’:

And pointing a browser at the public ip and port, the app is up and running! JAX-RS using WildFly Swarm, in a Docker container, deployed to IBM Bluemix!