Jocker is (yet another) Docker Client library to access Docker API.
Primary goals are to "keep it simple stupid" and avoid too many dependencies on third-party libraries
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.
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.
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
- 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
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:
- build the command line archive:
mvn compile assembly:single
- create an alias:
alias jocker="java -jar target/jocker-0.1-SNAPSHOT-jar-with-dependencies.jar"
- enjoy your new docker CLI :P
➜ jocker run -i --rm --name jocker alpine
echo hello $HOSTNAME
hello jocker
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);
}
- ContainerList
- ContainerCreate
- ContainerInspect
- ContainerTop
- ContainerLogs
- ContainerChanges
- ContainerExport
- ContainerStats
- ContainerResize
- ContainerStart
- ContainerStop
- ContainerRestart
- ContainerKill
- ContainerUpdate
- ContainerRename
- ContainerPause
- ContainerUnpause
- ContainerAttach
- ContainerAttachWebsocket
- ContainerWait
- ContainerDelete
- ContainerArchiveInfo
- ContainerArchive
- PutContainerArchive
- ContainerPrune
- ContainerAttach
- ImageList
- ImageBuild
- BuildPrune
- ImageCreate (aka "pull")
- ImageInspect
- ImageHistory
- ImagePush
- ImageTag
- ImageDelete
- ImageSearch
- ImagePrune
- ImageCommit
- ImageGet
- ImageGetAll
- ImageLoad
- NetworkList
- NetworkInspect
- NetworkDelete
- NetworkCreate
- NetworkConnect
- NetworkDisconnect
- NetworkPrune
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.
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 :
- 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.
- 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.