šŸ³ .NET (C#) Client Library for Docker API
C#
Latest commit 9d156d1 Feb 21, 2017 @jasoncouture jasoncouture committed with jterry75 Multiple issues fixed, see details (#170)
* CancellationToken support (#166)
Timeout configuration support (#168)
Fixed project files for VS2017 RC as noted here: https://aka.ms/sdkimplicititems (#169)

* Make DefaultTimeout an auto-property

* Fixed project files broken by merge.
It appears the merge removed the includes, but did not remove the added Ignore property, thus no files (or few files depending on the project) were loaded causing compilation to fail.

* Constructor change as requested by @jterry75

README.md

.NET Client for Docker Remote API

This library allows you to interact with Docker Remote API endpoints in your .NET applications.

It is fully asynchronous, designed to be non-blocking and object-oriented way to interact with your Docker daemon programmatically.

Versioning: For example, v2.124.0 supports v1.24 of Docker Remote API.

Installation

You can add this library to your project using NuGet. This is the only method this library is currently distributed unless you choose to build your own binaries using source code. Run the following command in the ā€œPackage Manager Consoleā€:

PM> Install-Package Docker.DotNet

Or right click to your project in Visual Studio, choose ā€œManage NuGet Packagesā€ and search for ā€˜Docker.DotNetā€™ and click ā€˜Installā€™. (see NuGet Gallery.)

Usage

You can initialize the client like the following:

using Docker.DotNet;
DockerClient client = new DockerClientConfiguration(new Uri("http://ubuntu-docker.cloudapp.net:4243"))
     .CreateClient();

Example: List containers

IList<ContainerResponse> containers = await client.Containers.ListContainersAsync(
    new ContainersListParameters(){
        Limit = 10,
    });

Example: Create an image by pulling from Docker Registry

The code below pulls fedora/memcached image to your Docker instance using your Docker Hub account. You can anonymously download the image as well by passing null instead of AuthConfig object:

Stream stream  = await client.Images.CreateImageAsync(new ImagesCreateParameters() {
    Parent = "fedora/memcached",
    Tag = "alpha",
}, new AuthConfig(){
    Email = "ahmetb@microsoft.com",
    Username = "ahmetalpbalkan",
    Password = "pa$$w0rd"
});

Example: Start a container

The following code will start the created container with specified host configuration object. This object is optional, therefore you can pass a null.

There is no usage of optional values in the method signatures, mostly because these behavior is undefined in Docker API as well.

await client.Containers.StartContainerAsync("39e3317fd258", new HostConfig(){
    DNS = new[] { "8.8.8.8", "8.8.4.4" }
});

Example: Stop a container

var stopped = await client.Containers.StopContainerAsync("39e3317fd258", new ContainerStopParameters(){
        WaitBeforeKillSeconds = 30
    },
    CancellationToken.None);

Above, the WaitBeforeKillSeconds field is of type uint? which means optional. This code will wait 30 seconds before killing it. If you like to cancel the waiting, you can use the CancellationToken parameter.

Example: Dealing with Stream responses

Some Docker API endpoints are designed to return stream responses. For example Monitoring Docker events continuously streams the status in a format like :

{"status":"create","id":"dfdf82bd3881","from":"base:latest","time":1374067924}
{"status":"start","id":"dfdf82bd3881","from":"base:latest","time":1374067924}
{"status":"stop","id":"dfdf82bd3881","from":"base:latest","time":1374067966}
{"status":"destroy","id":"dfdf82bd3881","from":"base:latest","time":1374067970}
...

To obtain this stream you can use:

CancellationTokenSource cancellation = new CancellationTokenSource();
Stream stream = await client.Miscellaneous.MonitorEventsAsync(new ContainerEventsParameters(), cancellation.Token);
// Initialize a StreamReader...

You can cancel streaming using the CancellationToken. On the other hand, if you wish to continuously stream, you can simply pass CancellationToken.None.

Example: HTTPS Authentication to Docker

If you are running Docker with TLS (HTTPS), you can authenticate to the Docker instance using the Docker.DotNet.X509 package. You can get this package from NuGet or by running the following command in the ā€œPackage Manager Consoleā€:

PM> Install-Package Docker.DotNet.X509

Once you add Docker.DotNet.X509 to your project, use CertificateCredentials type:

var credentials = new CertificateCredentials (new X509Certificate2 ("CertFile", "Password"));
var config = new DockerClientConfiguration("http://ubuntu-docker.cloudapp.net:4243", credentials);
DockerClient client = config.CreateClient();

If you don't want to authenticate you can omit the credentials parameter, which defaults to an AnonymousCredentials instance.

The CertFile in the example above should be a .pfx file (PKCS12 format), if you have .pem formatted certificates which Docker normally uses you can either convert it programmatically or use openssl tool to generate a .pfx:

openssl pkcs12 -export -inkey key.pem -in cert.pem -out key.pfx

(Here, your private key is key.pem, public key is cert.pem and output file is named key.pfx.) This will prompt a password for PFX file and then you can use this PFX file on Windows. If the certificate is self-signed, your application may reject the server certificate, in this case you might want to disable server certificate validation: ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, er) => true;

Example: Basic HTTP Authentication to Docker

If the Docker instance is secured with Basic HTTP Authentication, you can use the Docker.DotNet.BasicAuth package. Get this package from NuGet or by running the following command in the ā€œPackage Manager Consoleā€:

PM> Install-Package Docker.DotNet.BasicAuth

Once you added Docker.DotNet.BasicAuth to your project, use BasicAuthCredentials type:

var credentials = new BasicAuthCredentials ("YOUR_USERNAME", "YOUR_PASSWORD");
var config = new DockerClientConfiguration("tcp://ubuntu-docker.cloudapp.net:4243", credentials);
DockerClient client = config.CreateClient();

BasicAuthCredentials also accepts SecureString for username and password arguments.

Example: Specifying Remote API Version

By default this client does not specify version number to the API for the requests it makes. However, if you would like to make use of versioning feature of Docker Remote API You can initialize the client like the following.

var config = new DockerClientConfiguration(...);
DockerClient client = config.CreateClient(new Version(1, 16));

Error Handling

Here are typical exceptions thrown from the client library:

  • DockerApiException is thrown when Docker API responds with a non-success result. Subclasses:
    • DockerContainerNotFoundException
    • DockerImageNotFoundException
  • TaskCanceledException is thrown from System.Net.Http.HttpClient library by design. It is not a friendly exception, but it indicates your request has timed out. (default request timeout is 100 seconds.)
    • Long-running methods (e.g. WaitContainerAsync, StopContainerAsync) and methods that return Stream (e.g. CreateImageAsync, GetContainerLogsAsync) have timeout value overridden with infinite timespan by this library.
  • ArgumentNullException is thrown when one of the required parameters are missing/empty.
    • Consider reading the Docker Remote API reference and source code of the corresponding method you are going to use in from this library. This way you can easily find out which parameters are required and their format.

Versioning

Version if this package uses SemVer format: MAJOR.MINOR.PATCH. MINOR segment indicates the Docker Remote API version support. For instance v2.124.0 of this library supports Docker Remote API v1.24. This does not guarantee backwards compatibility as Docker Remote API does not guarantee that either.

MAJOR is preserved for major breaking changes we make to the library itself such as how the calls are made or how authentication is made. PATCH is just for incremental fixes.

Changelog

v2.124.0
======

This release contains breaking changes!

+ Updated to support Docker Engine API 1.24.
+ Types are now code generated from Docker source.

Acknowledgements
- Justin Terry (@jterry75)

v1.2.2
======
+ Added no/unless-stopped restart policies (#41)
+ Bugfix: streams are being closed prematurely (#42)
+ Added /containers/(id)/archive methods from Remote API v1.20 (#43)
+ Deprecated: CopyFromContainerAsync (in favor of archival methods) (#43)

Acknowledgements
- Oliver Neal (@ItsVeryWindy)


v1.2.1
======
+ Added missing restart policies no/unless-stopped
+ Added undefined restart policy (#36)
+ Use only Http handler per DockerClient instance (#40)

Acknowledgements
- Tugberk Ugurlu (@tugberkugurlu)


v1.2.0
======
+ Added `docker exec` endpoints support (#35)

Acknowledgements
- Ricardo Peres (@rjperes)

v1.1.2.1
========
+ Added support for Docker Remote API v1.16 (#19)
+ Bugfix: add Microsoft.Bcl.Async dependency (#19)
+ Bugfix: parameter conversion error in ListContainersParameters (#16)
+ Added support for RestartPolicy (#9)

Acknowledgements
- Josh Garverick (@jgarverick)
- Shakirov Ruslan (@build-your-web)

v1.1.1
======
+ Bugfix: infinite timeout for stream requests lost in PCL translation
+ New: support to specify a container name in CreateContainerAsync

Acknowledgemnets
- @jgarverick for implementing container name support
- Iouri Simernitski (@pefferie) for bug report

v1.1.0
======
+ PCL support
+ Support for Basic HTTP authentication
+ CertificateCredentials (X509) is now a separate package

Acknowledgements:
- @jgarverick for helping out extensively on PCL support
- @Gandalis for implementing basic auth

v1.0.0
======
+ Initial release

Known Issues / TODO

  • HTTP Hijacking is not implemented yet, therefore "Attach to Container" operation does not exist in the library (expecting pull requests!) A workaround might be using WebSockets (/attach/ws).
  • Certificate authentication does not work on Mono. [StackOverflow question]
  • Deserialization of DateTime fields from JSON responses will fail with System.FormatException on Mono due to Mono bug #22417. Any responses contain DateTime fields will fail on Mono.
  • Test suite does not exist. Functionality is verified manually. (pull requests are welcomed, I can provide a private test instance on cloud!)
  • CertificateCredentials class is not tested.
  • Ability to specify version and using that the request URI is not implemented.
  • Fields that could have been DateTime are either long or string because Docker API uses inconsistent date formats in the API (docker issue #7670).

License

Copyright 2016 Microsoft Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Authors/Contributors