Search code examples
c#dockerazure-service-fabricdocker-for-windowsservice-fabric-on-premises

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


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?


Solution

  • 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