Connect to docker_engine (named pipe) from a C# Service Fabric app on Windows

1k Views Asked by At

I have a Stateless Service Fabric project (.NET Core) that I need to kick off a Docker job from. I'm using Docker.DotNet and the following code works well in a small Console App, however will not work in Service Fabric:

var dockerClient = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine")).CreateClient();

// error occurs on next line (in Service Fabric)...
dockerClient.Images
    .CreateImageAsync(new ImagesCreateParameters
    {
        FromImage = "jbarlow83/ocrmypdf",
        Tag = "latest"
    },
        new AuthConfig(),
        new Progress<JSONMessage>());

I see this error in Service Fabric Explorer if I try to run it from the Stateless SF project:

System.UnauthorizedAccessException: Access to the path is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Pipes.NamedPipeClientStream.ConnectInternal(Int32 timeout, CancellationToken cancellationToken, Int32 startTime)
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Docker.DotNet.DockerClient.<>c__DisplayClass6_0.<<-ctor>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Net.Http.Client.ManagedHandler.d__33.MoveNext()

I'm not sure if this is actually a permission issue, or if it's related to how Service Fabric network isolation works.

I'm trying this on my local development instance, and this will eventually (hopefully) go to an on-premise setup.

Is there a way to access named pipes on the node that is hosting a SF application? Or perhaps another suggested way to run Docker through a .NET Core SF application?

2

There are 2 best solutions below

0
On BEST ANSWER

I was able to get this working by changing my DockerClientConfiguration line to no longer use named pipes, and instead use http://localhost:2375:

var dockerClient = new DockerClientConfiguration(new Uri("http://localhost:2375")).CreateClient();

And then enabled Expose daemon on tcp://localhost:2375 without TLS in the Docker CE General Settings:

enter image description here

2
On

Just came across this when I ran into this issue today, and ended up stumbling onto a different solution if you don't want to switch away from the Named Pipe connection. If you set up your Service Fabric service to run as a LocalSystem Account instead of the default account, it should work as well.

You can follow the instructions here to change the Account your Stateless Service runs under in the Manifest

This works because according to this article on Named Pipes, only certain types of accounts get access to the Named Pipe, one of which is LocalSystem.