Getting started with Docker management from .NET

...
  • By Ivan Gavryliuk
  • In Docker  |  .NET  |  C#
  • Posted 31/01/2020

There are times when you need to manage Docker infrastructure from .NET/C# - probably not an every day task, but it's definitely interesting. You could build your own monitoring solution, container management, automation and so on if you could use it from C#. Fortunately, this library exists and was created by Microsoft, so expect long support and high quality.

What could you build with Docker/C# integration? Here are some ideas:

  1. Next generation container orchestration solution such as a competitor to Kubernetes - very ambitions! Under the hood K8 is managing containers, so this can be your head start :)
  2. A desktop utility that manages developer's docker installation. This could be really cool considering the lack of good desktop software these days.
  3. Some awesome automated development utilities, for instance an IDE plugin (Visual Studio is a great candidate, as it natively supports .NET add-ins) that helps you automate stuff - take your code, deploy to Docker, maybe inject some debugger and so on.

These are just on top of my head.

Starting with this library is actually very trivial and surprisingly it just works - just reference Docker.DotNet NuGet package and start writing code.

Sample 1. Listing containers

This is the most trivial example and it just works:

var client = new DockerClientConfiguration(LocalDockerUri()).CreateClient();
	
var containers = await client.Containers.ListContainersAsync(new ContainersListParameters { All = true });	

containers.Select(c => c.Names).Dump();

private static Uri LocalDockerUri()
{
	bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

	return isWindows ? new Uri("npipe://./pipe/docker_engine") : new Uri("unix:/var/run/docker.sock");
}

Sample 2. Constantly Monitoring Container Status

This is a more interesting one - you can subscribe to container stats (memory, cpu usage and so on) and get notified regularly, then you can use that data somewhere else, like plot a chart.

await client.Containers.GetContainerStatsAsync(id,
	new ContainerStatsParameters
	{		
	},
	 new StatsProgress(), default);

public class StatsProgress : IProgress<ContainerStatsResponse>
{
	public void Report(ContainerStatsResponse value)
	{
		Console.WriteLine(value.ToString());
	}
}

Sample 3. Tailing Container Logs

Tailing logs is also really interesting, this could be essential if you want say build a log monitoring solution for docker. And there is API for this as well.

Stream logStream = await client.Containers.GetContainerLogsAsync(id,
		new ContainerLogsParameters
		{
			Follow = true,
			ShowStdout = true,
			ShowStderr = true,
			Timestamps = true
		},
		default);

using(var reader = new StreamReader(logStream))
{
	string line = null;
	while((line = await reader.ReadLineAsync()) != null)
	{
		Console.WriteLine(line);
	}
}

This essentially subscribes to log output of a particular container (Follow = true) and intercepts both error and stdout streams. Timestamps is optional and indicates whether you want to display timestamps at the beginning of each line - can be useful if software running in the container doesn't produce them.

You can use this to build some UI with colorisation and tailing like I've prototyped for myself:


Thanks for reading. If you would like to follow up with future posts please subscribe to my rss feed and/or follow me on twitter.