Sunday, June 5, 2022

Reading a file from a Docker container in .net core

In many situations it might be needed to read files from a docker container using .net code.
Docker.DotNet library is very useful to interact with docker from .net. And it provides a useful method (GetArchiveFromContainerAsync) to read files from a docker container.
When I tried to use this method to read a small csv/text file, the file content looked weird a bit. It seemed like there was an encoding issue!

When I checked the code on Github, I found that the returned data is a tarball stream. Which makes sense as Docker documentation mentions that the returned stream is a Tar stream.

To read the Tar stream, I tried to use SharpZipLib library's TarInputStream class. However, that didn't work as apparently the library requires a seekable stream while the stream contained in the GetArchiveFromContainerResponse returned from the method is not.
The workaround -which works well for relatively small files- is to copy the stream to a memory stream and use that instead.

This is a sample code:

DockerClientConfiguration config = new();
using var client = config.CreateClient();

GetArchiveFromContainerParameters parameters = new()
	Path = "/root/eula.1028.txt"
var file = await client.Containers.GetArchiveFromContainerAsync("example", parameters, false);

using var memoryStream = new MemoryStream();

memoryStream.Seek(0, SeekOrigin.Begin);

using var tarInput = new TarInputStream(memoryStream, Encoding.ASCII);

using var reader = new StreamReader(tarInput);

var content = reader.ReadToEnd();


I hope this helps!