Scott's Weblog The weblog of an IT pro specializing in cloud computing, virtualization, and networking, all with an open source view

Installing Older Docker Client Binaries on Fedora

Sometimes there’s a need to have different versions of the Docker client binary available. On Linux this can be a bit challenging because you don’t want to install a “full” Docker package (which would also include the Docker daemon); you only need the binary. In this article, I’ll outline a process I followed to get multiple (older) versions of the Docker client binary on my Fedora 27 laptop.

The process has two steps:

  1. Download the RPMs for the older releases from the Docker Yum repository (for Fedora, that repository is here).
  2. Extract the files from the RPM without actually installing the RPM.

For step 1, you can use the curl program to download specific RPMs. For example, to download version 1.12.6 of the Docker client binary, you’d download the appropriate RPM like this:

curl -LO

You’ll note that the URL above appears to be tied to a particular Fedora version (24, in this case). However, that’s only significant/applicable for the entire RPM package; once you extract the specific binaries, you should have no issues running the binaries on a different version (I was able to run older versions of Docker—ranging from 1.9.1 to 1.13.1—on Fedora 27 with no issues).

Once you have the RPM, you can use rpm2cpio and cpio (as outlined in this article) to extract the files inside the RPM. For example, to extract the files from the RPM downloaded above, you’d use a command like this:

rpm2cpio docker-engine-1.12.6-1.fc24.x86_64.rpm | cpio -idmv

This will extract all the individual files in the RPM package. In this specific example, you’ll see two directories created: a usr directory and an etc directory. Digging into the usr directory, you’ll find the docker client binary in a bin subdirectory. This client binary is really the only thing we need from the package, so we can copy it out:

cp usr/bin/docker ./docker-1.12.6

You’ll note that I “versioned” the file in the name, so as to make it easier for multiple versions of the Docker client binary to co-exist on the same Linux system.

With the Docker client binary extracted, we can remove the extracted files and the downloaded RPM package:

rm -rf etc
rm -rf usr
rm docker-engine-1.12.6-1.fc24.x86_64.rpm

(Important warning: you’ll note that my references to usr and etc lack a preceding forward slash, meaning I’m referencing directories named usr and etc in the current directory. Be sure you do not include the leading slash, or you’ll be in a world of hurt.)

You can place the extracted binary wherever you’d like (I like to use /opt/docker/bin), and repeat the process for a different version. Whenever you need to run a particular version of the Docker client, you have (at least) three options:

  1. Somewhere in your PATH, create a symbolic link named docker that points to the version you want to run. Then, just run docker like you normally would.
  2. Specify the full path to the client binary you want to run.
  3. Temporarily alias docker to the particular binary version you want.

If you plan on having a “full” Docker package installed on your Linux system (quite handy, by the way), then option #1 may be a bit more complicated; you may prefer option #2 or option #3. Option #3 probably provides the best balance between ease-of-use and flexibility. Your mileage may vary, of course.

Here’s hoping others find this information useful as well!

Installing Postman on Fedora 27

I recently had a need to install the Postman native app on Fedora 27. The Postman site itself only provides a link to the download and a rather generic set of instructions for installing the Postman native app (a link to these instructions for Ubuntu 16.04 is also provided). There were not, however, any directions for Fedora. Hence, I’m posting the steps I took to set up the Postman native app on my Fedora 27 laptop.

(Note that these instructions will probably work with other versions of Fedora as well, but I’ve only used them on Fedora 27.)

Here are the steps I followed:

  1. Download the installation tarball, either via your browser of choice or via the command line. If you’d prefer to use the command line, this command should take care of you:

    curl -L -O postman-linux-x64.tar.gz
  2. Unpack the tarball into the directory of your choice. I prefer to put third-party applications such as this into the /opt directory; you can (obviously) put it wherever you prefer. This command should do the trick:

    sudo tar xvzf postman-linux-x64.tar.gz -C /opt

    If you prefer a directory other than /opt, specify the appropriate directory in the command above.

  3. In my particular case, tar created a directory with an uppercase character (/opt/Postman) and some odd permissions (a strange user and group for ownership). I fixed those with mv and chown, respectively. You may or may not need to do anything.

  4. Create a symbolic link in a directory included in your PATH. In this example, I’m creating the symbolic link in /usr/local/bin, but you could use any directory included in your PATH:

    sudo ln -s /opt/postman/Postman /usr/local/bin/postman
  5. At this point, you should be able to launch Postman by just running postman from the terminal. However, ideally you’ll want to be able to use a graphical launcher. To do that, you need to create a “desktop launcher.” Create a file named postman.desktop in ~/.local/share/applications with these contents:

    [Desktop Entry]
    GenericName=API Client
    X-GNOME-FullName=Postman API Client
    Comment=Make and view REST API calls and responses
  6. Log out and log back in, and after a few minutes you should be able to see a Postman icon in your list of applications. You can now launch Postman either by using the graphical launcher or by running postman in the terminal.


Making AWS re:Invent More Family-Friendly

AWS re:Invent is just around the corner, and Spousetivities will be there to help bring a new level of family friendliness to the event. If you’re thinking of bringing a spouse, partner, or significant other with you to Las Vegas, I’d encourage you to strongly consider getting him or her involved in Spousetivities.

Want a sneak peek at what’s planned? Have a look:

  • Monday’s activity is a full-day trip to Death Valley, including a stop at Bad Water Basin (significant because it is 280 feet below sea level, making it the lowest place in the Western Hemisphere!). Lunch is included, of course.
  • On Tuesday, Spousetivities participants will get to visit a number of locations on the Las Vegas Strip, including Siegfried and Roy’s Secret Garden, the Wildlife Habitat at the Flamingo, and the Shark Reef at Mandalay Bay. Transportion is provided for longer connections, but there will be some walking involved—wear comfortable shoes!
  • Wednesday includes a visit to Red Rock Canyon and Hoover Dam. There will some opportunities for short sightseeing walks in Red Rock Canyon (plus the 13-mile scenic drive), and the Hoover Dam tour includes access to the generator room (a very cool sight).
  • Wrapping up the week on Thursday is a helicopter tour with views of the Hoover Dam, Lake Mead, Fortification Hill, the Colorado River, and—of course—the Grand Canyon! This includes a landing on the floor of the Grand Canyon for a snack and beverages. This is an amazing experience. (I’ve personally taken this tour and it is fabulous.)

Registration is open right now, so sign up before it’s too late. Prices for these activities is reduced from standard retail rates thanks to sponsorship from VMware NSX.

Technology Short Take 90

Welcome to Technology Short Take 90! This post is a bit shorter than most, as I’ve been on the road quite a bit recently. Nevertheless, there’s hopefully something here you’ll find useful.



Cloud Computing/Cloud Management

  • Google is rolling out Kubernetes 1.8 to Google Container Engine; this blog post talks about some of the new features and functionality.
  • Lior Kamrat has a multi-part series on an architecture that blends Mesosphere DC/OS, Azure, Docker, and VMware vSphere. Check out the beginning of the series here.

Operating Systems/Applications


  • I’m clearly behind the times in some of my reading, as this great article by J Metz was just brought to my attention recently. J does a good job of laying out the various competing forces that drive product/technology evolution and selection in the storage space, though one might argue these same forces are at work in other areas besides just storage.


Career/Soft Skills

Thanks for reading! Feel free to hit me up on Twitter if you have feedback or would like to share a link I should include in a future Technology Short Take.

How to Tag Docker Images with Git Commit Information

I’ve recently been working on a very simple Flask application that can be used as a demo application in containerized environments (here’s the GitHub repo). It’s nothing special, but it’s been useful for me as a learning exercise—both from a Docker image creation perspective as well as getting some additional Python knowledge. Along the way, I wanted to be able to track versions of the Docker image (and the Dockerfile used to create those images), and link those versions back to specific Git commits in the source repository. In this article, I’ll share a way I’ve found to tag Docker images with Git commit information.

Before I proceed any further, I’ll provide the disclaimer that this information isn’t unique; I’m building on the work of others. Other articles sharing similar information include this one; no doubt there are countless more I haven’t yet seen. I’m presenting this information here simply to show one way (not the only way) of including Git commit information with a Docker image.

Getting the necessary information from Git is actually far easier than one might think. This variation of the git log command will print only the full hash of the last commit to the repository:

git log -1 --format=%H

If you prefer the shortened commit hash (which is what I use currently), then just change the %H to %h, like this:

git log -1 --format=%h

Getting the information out of Git is only half the puzzle, though; the other half is getting it into the Docker image. The answer lies in some changes to the Dockerfile and the use of an additional command-line flag when building the image.

First, you’ll need to add lines like this to your Dockerfile:

ARG GIT_COMMIT=unspecified
LABEL git_commit=$GIT_COMMIT

The first line defines a build-time argument, and the use of =unspecified means that if the built-time argument is omitted or not supplied, it will default to the value of “unspecified”. The second line takes the information from the argument and adds it as a label on the image.

With the Dockerfile prepared to leverage Git commit information, all that’s necessary is to build the image with the --build-arg flag, like this (here I’m showing the command I’d use to build the “flask-web-svc” image for the Flask application I’ve been building):

docker build -t flask-local-build --build-arg GIT_COMMIT=$(git log -1 --format=%h) .

Here I’m using Bash command substitution to take the output of git log -1 --format=%h and supply it to docker build as the GIT_COMMIT argument (i.e., what the Dockerfile is expecting). This command assumes that you’re building the Docker image from the latest Git commit; if this isn’t the case, then you’ll need to modify your command. As I mentioned earlier, if you omit the --build-arg parameter, then the label will be assigned with the default value of “unspecified”.

When you build the image this way, you can then see the Git commit attached to the image as a label using this command:

docker inspect flask-local-build | jq '.[].ContainerConfig.Labels'

Note I’m using the incredibly-useful jq tool here. (If you’re not familiar with jq, check out my introductory post.)

Assuming that the build was successful and the container operates as expected/desired, then you can tag the image and push it to a registry:

docker tag flask-local-build slowe/flask-web-svc:0.3
docker push slowe/flask-web-svc:0.3

I also create a GitHub release corresponding to the Git commit used to build an image, so I can easily correlate a particular version of the Docker image with the appropriate commit in the repository. This makes it easier to quickly jump to the Dockerfile for each version of the Docker image. So, for example, when I release version 0.3 of the Docker image (which I recently did), I also have a matching v0.3 release in GitHub that points to the specific Git commit from which version 0.3 of the Docker image is built. This allows me—and anyone else consuming my Docker image—to have full traceability from a particular version of a Docker image all the way back to the specific Git commit from which that Docker image was built.

I imagine there are probably better/more efficient ways of doing what I’ve done here; feel free to hit me up on Twitter to help me improve. Thanks for reading!

UPDATE: Michael Gasch also pointed out that git rev-parse HEAD will return the full (long) commit hash from the last commit, so this is another way to get the information from Git. Given the nature of Git, no doubt there are countless more!

Recent Posts

Deep Dive into Container Images in Kolla

This is a liveblog of my last session at the Sydney OpenStack Summit. The session title is “OpenStack images that fit your imagination: deep dive into container images in Kolla.” The presenters are Vikram Hosakote and Rich Wellum, from Cisco and Lenovo, respectively.


Carrier-Grade SDN-Based OpenStack Networking Solution

This session was titled “Carrier-Grade SDN Based OpenStack Networking Solution,” led by Daniel Park and Sangho Shin. Both Park and Shin are from SK Telecom (SKT), and (based on the description) this session is a follow-up to a session from the Boston summit where SK Telecom talked about an SDN-based networking solution they’d developed and released for use in their own 5G-based network.


Can OpenStack Beat AWS in Price

This is a liveblog of the session titled “Can OpenStack Beat AWS in Price: The Trilogy”. The presenters are Rico Lin, Bruno Lago, and Jean-Daniel Bonnetot. The “trilogy” refers to the third iteration of this presentation; each time the comparison has been done in a different geographical region (first in Europe, then in North America, and finally here in Asia-Pacific).


Lessons Learnt from Running a Container-Native Cloud

This is a liveblog of the session titled “Lessons Learnt from Running a Container-Native Cloud,” led by Xu Wang. Wang is the CTO and co-founder of, a company that has been working on leveraging hypervisor isolation for containers. This session claims to discuss some lessons learned from running a cloud leveraging this sort of technology.


Make Your Application Serverless

This is a liveblog from the last day of the OpenStack Summit in Sydney, Australia. The title of the session is “Make Your Application Serverless,” and discusses Qinling, a project for serverless (Functions-as-a-Service, or FaaS) architectures/applications on OpenStack. The presenters for the session are Lingxian Kong and Feilong Wang from Catalyst Cloud.


How to Deploy 800 Servers in 8 Hours

This is a liveblog of the session titled “How to deploy 800 nodes in 8 hours automatically”, presented by Tao Chen with T2Cloud (Tencent).


IPv6 Primer for Deployments

This is a liveblog of the OpenStack Summit Sydney session titled “IPv6 Primer for Deployments”, led by Trent Lloyd from Canonical. IPv6 is a topic with which I know I need to get more familiar, so attending this session seemed like a reasonable approach.


Battle Scars from OpenStack Deployments

This is the first liveblog from day 2 of the OpenStack Summit in Sydney, Australia. The title of the session is “Battle Scars from OpenStack Deployments.” The speakers are Anupriya Ramraj, Rick Mathot, and Farhad Sayeed (two vendors and an end-user, respectively, if my information is correct). I’m hoping for some useful, practical, real-world information out of this session.


Kubernetes on OpenStack: The Technical Details

This is a liveblog of the OpenStack Summit session titled “Kubernetes on OpenStack: The Technical Details”. The speaker is Angus Lees from Bitnami. This is listed as an Advanced session, so I’m hoping we’ll get into some real depth in the session.


Issues with OpenStack That Are Not OpenStack Issues

This is a liveblog of OpenStack Summit session on Monday afternoon titled “Issues with OpenStack that are not OpenStack Issues”. The speaker for the session is Sven Michels. The premise of the session, as I understand it, is to discuss issues that arise during OpenStack deployments that aren’t actually issues with OpenStack (but instead may be issues with process or culture).


To K8s or Not to K8s Your OpenStack Control Plane

This is a liveblog of the Monday afternoon OpenStack Summit session titled “To K8s or Not to K8s Your OpenStack Control Plane”. The speaker is Robert Starmer of Kumulus Technologies. This session is listed as a Beginner-level session, so I’m hoping it’s not too basic for me (and that readers will still get some value from the liveblog).


OpenStack Summit Sydney Day 1 Keynote

This is a liveblog of the day 1 keynote here at the OpenStack Summit in Sydney, Australia. I think this is my third or fourth trip to Sydney, and this is the first time I’ve run into inclement weather; it’s cloudy, rainy, and wet here, and forecasted to remain that way for most of the Summit.


A Sublime Text Keymap for Bracketeer

I’ve made no secret of the fact that I’m a fan of Sublime Text (ST). I’ve evaluated other editors, like Atom, but still find that ST offers the right blend of performance, functionality, customizability, and cross-platform support. One nice thing about ST (other editors have this too) is the ability to extend it via packages. Bracketeer is one of many packages that can be used to customize ST’s behavior; in this post, I’d like to share a keymap I’m using with Bracketeer that I’ve found very helpful.


Strange Error with the Azure CLI

Over the last week or so, I’ve been trying to spend more time with Microsoft Azure; specifically, around some of the interesting things that Azure is doing with containers and Kubernetes. Inspired by articles such as this one, I thought it would be a pretty straightforward process to use the Azure CLI to spin up a Kubernetes cluster and mess around a bit. Simple, right?


Technology Short Take 89

Welcome to Technology Short Take 89! I have a collection of newer materials and some older materials this time around, but hopefully all of them are still useful. (I needed to do some housekeeping on my Instapaper account, which is where I bookmark stuff that frequently lands here.) Enjoy!


Older Posts

Find more posts by browsing the post categories, content tags, or site archives pages. Thanks for visiting!