/jocker

Java Docker API Client relying on plain Socket

Primary LanguageJavaBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

ci status

Jocker, a Java client library for Docker API

Jocker is (yet another) Docker Client library to access Docker API.

logo

Primary goals are to "keep it simple stupid" and avoid too many dependencies on third-party libraries

Limited dependencies

Most docker client libraries rely on other libs, typically Rest frameworks like Jersey or a full featured HTTP client like Apache Http Client or Netty.

Jocker was initialy designed in the context of Jenkins Docker plugin development. Third party dependencies are constrained in Jenkins by core dependencies, introducing various classpath issues.

Also, such full-features HTTP client libraries demonstrated to have issues supporting some uncommon HTTP usage in docker APi, like Hijacked HTTP connection to set a bidirectional stdin/stdout multiplexed stream in interactive mode, or support for /var/run/docker.sock Unix Domain Socket.

For JSON (un)marshalling we rely on Google Gson as a tiny (standalone), simple and efficient JSON library.

KISS (Keep It Simple Stupid)

API model is generated from the Docker official OpenAPI specification. Some pull-requests have been made to help improve this API spec and ensure we get a clean model generated. For the few corner cases where the generated model doesn't offer a nice API, we maintain some dedicated model classes.

Jocker implement HTTP as plain text over a java.net.Socket. This allows transparent support for Unix Domain Socket thanks to junixsocket. Also can benefit java Channels for non-blocking I/Os without much efforts.

We don't claim to offer a full featured HTTP client, just implemented what's required for a Docker API server. HTTP, a plain value protocol, is easy to debug and to implement, with only some limited features required by Docker API. The HTTP client implementation is about ~100 lines of code. Doing so, we have full control on HTTP frames and headers over transport, and typically can implement HTTP connection Hijack without any hack.

License

Licensed under BSD Copyright 2017 Nicolas De Loof, Docker Inc.

tl;dr: You're free to use this code, make any changes you need, have fun with it. Contributions are welcome if you do something you consider useful :P

Future plans

  • implement all APIs
  • a fluent client for those who prefer this programming model
  • a swagger codegen template so we generate a plain json-P parser and don't need Gson (code is generated, not intended to be edited)
  • use java.nio Channels and jnr-unixsocket to rely on non-blocking I/O
  • conquer the world

How about Docker command line?

Jocker is desgined as a Docker API client, which for many commands is more-or-less equivalent with the docker command line verbs and flags, with a significant exception for docker run.

For demonstration purpose, Jocker do include com.docker.jocker.cli package which is not intended to be used for anything but experiments and demonstration. Still you can read this code and understand how to fill the gap between the command line you know and the actual API calls.

If you want to run Jocker as a "command line" demo, just:

  1. build the command line archive: mvn compile assembly:single
  2. create an alias: alias jocker="java -jar target/jocker-0.1-SNAPSHOT-jar-with-dependencies.jar"
  3. enjoy your new docker CLI :P
jocker run -i --rm --name jocker alpine
echo hello $HOSTNAME
hello jocker

Supported APIs :

Missing something ?

If you miss some API support in following list, please consider contributing. In most cases, this is just a question of implementing few lines of code. API type is already generated from docker's swagger API contract, so you only have to implement the method invocation based on API documentation.

public SomeType apiMethod(String param) {
    StringBuilder path = new StringBuilder("/v").append(version).append("/some/api?param=").append(param);
    Response r = doGET(path.toString());
    return gson.fromJson(r.getBody(), SomeType.class);
}

General purpose

Containers

Images

Exec

Networks

Volumes

Docker Swarm support

There's no short term plan to implement swarm related APIs (Nodes, Services, Tasks, Secrets, Configs) But feel free to contribute if you consider this a usefull addition.

Debug / Reverse engineering

There's few places where the docker API is not well documented, for sample ImageBuild operation documentation doesn't tell us much about the outputstream. In such circumstances we will have to reverse-engineer the docker API. Two (complementary) options here :

  1. read source code. If you're not familiar with Go this might be a bit challenging, but one learns a lot about the API looking at this.
  2. analyze HTTP traffic produced by docker CLI. For this purpose I use dockins/dockersock docker image to expose my docker4mac socket in plain HTTP :

docker run -it -v /var/run/docker.sock:/var/run/docker.sock -p 2375:2375 dockins/dockersock

Then I use Wireshark with filter tcp.port==2375 to capture HTTP frames sent by client and daemon response.