Displaying Docker containers and their history with Go

What Changed?

Finally, the program maintains in its right subwindow a history log of all containers that appear and later go away. For this, Listing 4 compares two string array slices in the diff() function and determines which new entries have been added in the second array and which entries are in the first array but have not made it into the second.

Unix experts know the procedure from the diff tool, which also displays the difference between two files in terms of lines that have either been added or omitted. Figure 2 illustrates that diff correctly finds out that the bar and zap entries have been removed from the test1.txt file and that the pow entry has been added to test2.txt.

Figure 2: The diff algorithm is based on the LCS method.

Smart Algorithm

How does the diff algorithm work? The basis is the longest common subsequence (LCS) procedure [6], which determines the longest common partial sequence of two arrays. A naive approach could simply delete all entries from the first array and add all items of the second array to arrive at the result. But that's not the point: It's about getting from A to B with as few steps as possible.

The LCS method provides a series of identical positions in both strings. In this way, it determines that the first entry foo occurs at the same position in both strings. The baz entry, on the other hand, has been shifted: In the first string, it is at the third position; in the second, it is at the second position (index (2,1)). The LCS algorithm therefore outputs the pairs (0,0),(2,1) when comparing the files test1.txt and test2.txt, as shown in Figure 3.

Figure 3: LCS pairs for the arrays from Figure 2.

Listing 4 retrieves the LCS algorithm from the golcs project on GitHub. From the delivered pairs, the code calculates container names to add and to remove. In order to move from the last list to the current one, it traverses the old and new arrays (left and right) step by step using for loops, while moving from pair to pair.

One difficulty here is the strict type system in Go: The LCS algorithm on GitHub was implemented with a generic type (interface{}), similar to void in C, because it is supposed to be able to analyze data of any type. To be able to process arrays of strings, however, the programmer needs to convert them into arrays of interface{} types first, which is laborious and time-consuming. Otherwise the compiler refuses to call the library function. The reason given by Go followers is that strings have a different memory layout than interface{} types. This mess will hopefully be resolved by the next Go version.

Conclusions and Outlook

Granted, the procedure for determining the Docker history is not 100 percent accurate. Between two queries, the Docker daemon could have created a container that disappeared on the second call. A ghost container of this kind could only be detected by a subscription mechanism that would receive a message from the Docker daemon on each event. Maybe I'll add it in the next iteration of this project.

The procedure is still good enough to observe appearing and vanishing containers and will help to detect any irregularities. Since it is a DIY program, there are no limits to the developer's creativity: Click on a displayed container and it shuts down? Sort by alphabetical order rather than by start date? Make missing containers red and new ones green? As always, the solution is just a few keystrokes away.


  1. "A Go terminal UI for displaying network adapters in real time" by Mike Schilli, Linux Magazine, issue 218, January 2019, pp. 42-45
  2. "Calculating weekdays and dates with Go" by Mike Schilli, Linux Magazine issue 227, October 2019, pp. 44-47
  3. "Go program stores directory paths" by Mike Schilli, Linux Magazine, issue 228, November 2019, pp. 42-45
  4. Listings for this article: ftp://ftp.linux-magazine.com/pub/listings/linux-magazine.com/231/
  5. Docker Client API: https://godoc.org/github.com/docker/docker/client#Client
  6. LCS: https://en.wikipedia.org/wiki/Longest_common_subsequence_problem

The Author

Mike Schilli works as a software engineer in the San Francisco Bay area, California. Each month in his column, which has been running since 1997, he researches practical applications of various programming languages. If you email him at mailto:mschilli@perlmeister.com he will gladly answer any questions.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • What's Going On?

    Experienced sys admins always use the same commands to analyze problematic system loads on Linux. Mike Schilli bundles them into a handy Go tool that shows all the results at a glance.

  • Tutorials – Docker

    You might think Docker is a tool reserved for gnarly sys admins, useful only to service companies that run complicated SaaS applications, but that is not true: Docker is useful for everybody.

  • Docker Open Source Developer Tools

    Docker provides the open source tools and resources for compiling, building, and testing containerized applications.

  • Ansible Container Auto Deploy

    Streamline software deployment with Ansible and Docker containers.

  • Docker with OwnCloud

    Run your application smoothly and portably in the cloud with the Docker container system. This workshop takes a practical look deploying Docker with the OwnCloud cloud environment.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More