Giter Club home page Giter Club logo

docker-client's Introduction

Docker Client

Build Status codecov Maven Central License

Status: mature

Spotify no longer uses recent versions of this project internally. The version of docker-client we're using is whatever helios has in its pom.xml. At this point, we're not developing or accepting new features or even fixing non-critical bugs. Feel free to fork this repo though.

This is a Docker client written in Java. It is used in many critical production systems at Spotify.

Version compatibility

docker-client is built and tested against the six most recent minor releases of Docker. Right now these are 17.03.1ce - 17.12.1ce (specifically the ones here). We upload the artifact tested on Docker 17.12.1~ce. See Docker docs on the mapping between Docker version and API version.

Download

Download the latest JAR or grab via Maven.

<dependency>
  <groupId>com.spotify</groupId>
  <artifactId>docker-client</artifactId>
  <version>LATEST-VERSION</version>
</dependency>

Usage Example

// Create a client based on DOCKER_HOST and DOCKER_CERT_PATH env vars
final DockerClient docker = DefaultDockerClient.fromEnv().build();

// Pull an image
docker.pull("busybox");

// Bind container ports to host ports
final String[] ports = {"80", "22"};
final Map<String, List<PortBinding>> portBindings = new HashMap<>();
for (String port : ports) {
    List<PortBinding> hostPorts = new ArrayList<>();
    hostPorts.add(PortBinding.of("0.0.0.0", port));
    portBindings.put(port, hostPorts);
}

// Bind container port 443 to an automatically allocated available host port.
List<PortBinding> randomPort = new ArrayList<>();
randomPort.add(PortBinding.randomPort("0.0.0.0"));
portBindings.put("443", randomPort);

final HostConfig hostConfig = HostConfig.builder().portBindings(portBindings).build();

// Create container with exposed ports
final ContainerConfig containerConfig = ContainerConfig.builder()
    .hostConfig(hostConfig)
    .image("busybox").exposedPorts(ports)
    .cmd("sh", "-c", "while :; do sleep 1; done")
    .build();

final ContainerCreation creation = docker.createContainer(containerConfig);
final String id = creation.id();

// Inspect container
final ContainerInfo info = docker.inspectContainer(id);

// Start container
docker.startContainer(id);

// Exec command inside running container with attached STDOUT and STDERR
final String[] command = {"sh", "-c", "ls"};
final ExecCreation execCreation = docker.execCreate(
    id, command, DockerClient.ExecCreateParam.attachStdout(),
    DockerClient.ExecCreateParam.attachStderr());
final LogStream output = docker.execStart(execCreation.id());
final String execOutput = output.readFully();

// Kill container
docker.killContainer(id);

// Remove container
docker.removeContainer(id);

// Close the docker client
docker.close();

Getting Started

If you're looking for how to use docker-client, see the User Manual. If you're looking for how to build and develop it, keep reading.

Prerequisites

docker-client should be buildable on any platform with Docker 1.6+, JDK8+, and a recent version of Maven 3.

A note on using Docker for Mac

If you are using Docker for Mac and DefaultDockerClient.fromEnv(), it might not be clear what value to use for the DOCKER_HOST environment variable. The value you should use is DOCKER_HOST=unix:///var/run/docker.sock, at least as of version 1.11.1-beta11.

As of version 4.0.8 of docker-client, DefaultDockerClient.fromEnv() uses unix:///var/run/docker.sock on OS X by default.

Testing

If you're running a recent version of docker (>= 1.12), which contains native swarm support, please ensure that you run docker swarm init to initialize the docker swarm.

Make sure Docker daemon is running and that you can do docker ps.

You can run tests on their own with mvn test. Note that the tests start and stop a large number of containers, so the list of containers you see with docker ps -a will start to get pretty long after many test runs. You may find it helpful to occasionally issue docker rm $(docker ps -aq).

Releasing

Commits to the master branch will trigger our continuous integration agent to build the jar and release by uploading to Sonatype. If you are a project maintainer with the necessary credentials, you can also build and release locally by running the below.

mvn clean [-DskipTests -Darguments=-DskipTests] -Dgpg.keyname=<key ID used for signing artifacts> release:prepare release:perform

A note on shading

Please note that in releases 2.7.6 and earlier, the default artifact was the shaded version. When upgrading to version 2.7.7, you will need to include the shaded classifier if you relied on the shaded dependencies in the docker-client jar.

Standard:

<dependency>
  <groupId>com.spotify</groupId>
  <artifactId>docker-client</artifactId>
  <version>3.5.12</version>
</dependency>

Shaded:

<dependency>
  <groupId>com.spotify</groupId>
  <artifactId>docker-client</artifactId>
  <classifier>shaded</classifier>
  <version>3.5.12</version>
</dependency>

This is particularly important if you use Jersey 1.x in your project. To avoid conflicts with docker-client and Jersey 2.x, you will need to explicitly specify the shaded version above.

Code of conduct

This project adheres to the Open Code of Conduct. By participating, you are expected to honor this code.

docker-client's People

Contributors

alexsapran avatar brujoand avatar catalyst7193 avatar cgnonofr avatar danielnorberg avatar davidxia avatar dflemstr avatar diptanu avatar dmandalidis avatar drewcsillag avatar fdonze avatar huadong avatar jan-zajic avatar johnflavin avatar leonverschuren avatar loicortola avatar marcolotz avatar mattnworb avatar mbaechler avatar mbruggmann avatar mosheeshel avatar mthmulders avatar rculbertson avatar rgrunber avatar rohansingh avatar sale87 avatar smythie86 avatar spotify-helios-ci-agent avatar stephan-huttenhuis avatar xcoulon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-client's Issues

Eliminate version from URI (or make configurable)

After many days spent trying to figure out why pulls from my local docker-registry weren't working, I tracked it down to the "v1.12" version string that's added to all API calls. For some reason, when doing a POST to /v1.12/image/create, the docker daemon times out trying to connect to the docker-registry (though, in fact, it never actually tries to connect).

Dropping the version string entirely makes everything work. So, my request is for either dropping the version string, which is probably too risky, or making the version string configurable.

If making it configurable is an acceptable approach, I can submit a pull request for that change.

Syntax for Volumes

I can't seem to figure out how to add a volume to my container from the host filesystem. I added the volume to my ContainerConfig but then at runtime it's missing from the container. It does however show up in my /var/lib/docker/containers/<container_id>/config.json file. Can someone write a little example of how to bind a volume?

Add "top" (ps inside container)

I'd like to see the "top" command added (I have this working locally), but I also wonder if a refactoring is in order to make adding new commands easier?

testSsl fails for me because container's port isn't ready yet

testSsl fails for me with this error on the ping.

testSsl(com.spotify.docker.client.DefaultDockerClientTest): java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: org.apache.http.conn.HttpHostConnectException: Connect to 192.168.59.103:49158 [/192.168.59.103] failed: Connection refused

But if I add Thread.sleep(60) right before line 941, it works. Is it because a container configured with SSL takes longer to start listening for connections? The test checks that the container is already running here.

[2.7.6] Logs w/ follow hangs, or finalizer error

My code is starting a Docker container with a Postgres instance inside, and waiting for the output to include the text "database system is ready to accept connections".

My code works fine ... but after I see the target text things go wonky.

If I close the LogStream, my process hangs for a while, then gets an exception:

(start-container)
09:07:27.965 INFO  no-correlation-id [nREPL-worker-3] c.s.d.c.DefaultDockerClient - Creating container with ContainerConfig: ContainerConfig{hostname=null, domainname=null, username=null, memory=null, memorySwap=null, cpuShares=null, cpuset=null, attachStdin=null, attachStdout=null, attachStderr=null, portSpecs=[62890:5432], exposedPorts=null, tty=null, openStdin=null, stdinOnce=null, env=null, cmd=null, image=quay.io/aviso/combined-db-migrated, volumes=null, workingDir=null, entrypoint=null, networkDisabled=null, onBuild=null}
09:07:28.096 INFO  no-correlation-id [nREPL-worker-3] c.s.d.c.DefaultDockerClient - Starting container with HostConfig: HostConfig{binds=null, containerIDFile=null, lxcConf=null, privileged=null, portBindings=null, links=null, publishAllPorts=null, dns=null, dnsSearch=null, volumesFrom=null, networkMode=null}
2015-02-18 17:07:10 UTC LOG:  database system was interrupted; last known up at 2015-02-12 21:40:56 UTC
2015-02-18 17:07:10 UTC LOG:  database system was not properly shut down; automatic recovery in progress
2015-02-18 17:07:10 UTC LOG:  redo starts at 0/1792078
2015-02-18 17:07:10 UTC LOG:  record with zero length at 0/19DD660
2015-02-18 17:07:10 UTC LOG:  redo done at 0/19DD620
2015-02-18 17:07:10 UTC LOG:  last completed transaction was at log time 2015-02-12 21:41:06.015063+00
2015-02-18 17:07:11 UTC LOG:  autovacuum launcher started
2015-02-18 17:07:11 UTC LOG:  database system is ready to accept connections
up and running!
java.net.SocketTimeoutException: Read timed out
     java.lang.RuntimeException: java.net.SocketTimeoutException: Read timed out
(pst)
                                                                          clojure.core/eval                          core.clj: 3076
                                                                                        ...                                        
                                                                      docker-utils/eval6732  form-init5456222565433859833.clj:    1
                                                               docker-utils/start-container                  docker_utils.clj:  151
                                                              docker-utils/launch-container                  docker_utils.clj:  128
                                                             docker-utils/wait-for-startup2                  docker_utils.clj:  110
                                                  com.spotify.docker.client.LogStream.close                    LogStream.java:   74
                                                  com.spotify.docker.client.LogReader.close                    LogReader.java:   88
                                                      com.google.common.io.ByteStreams.copy                  ByteStreams.java:  175
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream.read    ReaderInterceptorExecutor.java:  295
                               org.glassfish.jersey.message.internal.EntityInputStream.read            EntityInputStream.java:   96
                                                             java.io.FilterInputStream.read            FilterInputStream.java:  107
                                                             java.io.FilterInputStream.read            FilterInputStream.java:  133
                                                           java.io.BufferedInputStream.read          BufferedInputStream.java:  334
                                                          java.io.BufferedInputStream.read1          BufferedInputStream.java:  275
                                                           java.io.BufferedInputStream.fill          BufferedInputStream.java:  235
                                             org.apache.http.conn.EofSensorInputStream.read         EofSensorInputStream.java:  137
                                            org.apache.http.impl.io.ChunkedInputStream.read           ChunkedInputStream.java:  169
                                       org.apache.http.impl.io.ChunkedInputStream.nextChunk           ChunkedInputStream.java:  206
                                    org.apache.http.impl.io.ChunkedInputStream.getChunkSize           ChunkedInputStream.java:  240
                                    org.apache.http.impl.io.SessionInputBufferImpl.readLine       SessionInputBufferImpl.java:  270
                                  org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer       SessionInputBufferImpl.java:  152
                                  org.apache.http.impl.io.SessionInputBufferImpl.streamRead       SessionInputBufferImpl.java:  136
                                                            java.net.SocketInputStream.read            SocketInputStream.java:  121
                                                            java.net.SocketInputStream.read            SocketInputStream.java:  150
                                                     java.net.SocketInputStream.socketRead0            SocketInputStream.java      
java.net.SocketTimeoutException: Read timed out
     java.lang.RuntimeException: java.net.SocketTimeoutException: Read timed out

(Obviously, I'm working in Clojure, but that should hopefully not be relevant).

On the other hand, if I skip the close step, things work fine ... but at some future point, I see this error in my console:

(System/gc)
=> nil
09:09:19.238 WARN  no-correlation-id [Finalizer] c.s.d.c.LogStream - com.spotify.docker.client.LogStream@79220f71 not closed properly

If it helps, here's the code:

(defn- wait-for-startup2
  "Waits for the container to startup. Returns nil or throws an exception."
  [docker-client container-id container-name]
  ;; docker logs outputs to STDERR for some reason
  (let [^LogStream logs (.. docker-client (logs container-id (into-array DockerClient$LogsParameter [DockerClient$LogsParameter/STDERR
                                                                                                     DockerClient$LogsParameter/FOLLOW])))
        utf-8           Charsets/UTF_8
        ;; A bit cumbersome to get the logs
        cmd-fn          (fn []
                          (if (.hasNext logs)
                            (->> logs .next .content (.decode utf-8) .toString)))
        test-fn         (fn [line]
                          (print line)
                          (and line
                               (re-find #"database system is ready to accept connections" line)))
        wait-result     (wait-until cmd-fn test-fn 5000)]

    (println "up and running!")

    ; (.close logs)

    (if (= ::timeout wait-result)
      (throw (DockerException. (format "Docker container `%s' did not complete initialization before timeout." container-name))))))

Client termination problem

I am calling the DefaultDockerClient from within a class that is run via the java goal of the exec-maven-plugin. All of the operations I do works fine but the procedure does not terminate. It seems as if the DefaultDockerClient creates some resource (e.g. thread) that do not allow my procedure to terminate. After 15 seconds of activity the exec plugin forcefully terminates. Any idea what this is and what could be done?

Client timeout if an image build steps takes more than 30 seconds

My build context is about 1 GB and it takes a minute or two to transfer. Also, I don't want it compressed, most of it is already compressed files. The 30 seconds timeout in DockerCilent is not enough to complete this build:

Caused by: com.spotify.docker.client.DockerTimeoutException: Timeout: POST http://localhost:4243/v1.12/build
at com.spotify.docker.client.ProgressStream.hasNextMessage(ProgressStream.java:59)
at com.spotify.docker.client.DefaultDockerClient.build(DefaultDockerClient.java:688)
at com.spotify.docker.client.DefaultDockerClient.build(DefaultDockerClient.java:651)
...
Caused by: java.net.SocketTimeoutException: Read timed out
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:136)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:152)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:270)
at org.apache.http.impl.io.ChunkedInputStream.getChunkSize(ChunkedInputStream.java:240)
at org.apache.http.impl.io.ChunkedInputStream.nextChunk(ChunkedInputStream.java:206)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:169)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:137)
at org.glassfish.jersey.message.internal.EntityInputStream.read(EntityInputStream.java:101)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream.read(ReaderInterceptorExecutor.java:300)
at com.spotify.docker.client.shaded.com.fasterxml.jackson.core.json.UTF8StreamJsonParser.loadMore(UTF8StreamJsonParser.java:169)
at com.spotify.docker.client.shaded.com.fasterxml.jackson.core.json.UTF8StreamJsonParser._skipWSOrEnd(UTF8StreamJsonParser.java:2495)
at com.spotify.docker.client.shaded.com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:617)
at com.spotify.docker.client.shaded.com.fasterxml.jackson.databind.MappingIterator.hasNextValue(MappingIterator.java:159)
at com.spotify.docker.client.ProgressStream.hasNextMessage(ProgressStream.java:57)
... 56 more

I think build() should use noTimeoutResource() instead of resource().

Passing FileInputStream respectively tar file to custom build method doesn't work (?)

Hi,

I'm trying to add the docker-client to an application (interface) which is integrated into another application (interface) via maven dependencies.

I've added a second build method (buildFromFile) which builds a container from a tar archive containing all the files and the dockerfile instead of building a tar file from a directory as it's currently implemented.

So this works:

docker-client TestClient: works

app1 TestClient --> client app: works

but:

app2 TestClient --> app1 --> client: this error:

com.spotify.docker.client.DockerException: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: Unable to invoke request
at com.spotify.docker.client.DefaultDockerClient.propagate(DefaultDockerClient.java:1094)
at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:1034)
at com.spotify.docker.client.DefaultDockerClient.buildFromFile(DefaultDockerClient.java:810)
at com.spotify.docker.client.DefaultDockerClient.buildFromFile(DefaultDockerClient.java:735)
at docker.DockerImageMgmt.addImage(DockerImageMgmt.java:66)
at docker.DockerIaaSInterface.addImage(DockerIaaSInterface.java:42)
at TestClient.main(TestClient.java:30)
Caused by: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: Unable to invoke request
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:188)
at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:1032)
... 5 more
Caused by: javax.ws.rs.ProcessingException: Unable to invoke request
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:287)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:407)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:442)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation$2.call(ClientInvocation.java:477)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.ws.rs.ProcessingException: could not find writer for content-type application/tar type: java.io.File
at org.jboss.resteasy.core.interception.ClientWriterInterceptorContext.throwWriterNotFoundException(ClientWriterInterceptorContext.java:40)
at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.getWriter(AbstractWriterInterceptorContext.java:138)
at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:117)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.writeRequestBody(ClientInvocation.java:341)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.writeRequestBodyToOutputStream(ApacheHttpClient4Engine.java:558)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.buildEntity(ApacheHttpClient4Engine.java:524)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.loadHttpMethod(ApacheHttpClient4Engine.java:423)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:281)
... 7 more

I have no idea how to fix this... googling for "could not find writer for content-type application/tar type: java.io.File" doesn't bring up anything.

Does anyone know what might be causing this?

BR
Daniel

Connection to local docker

hey,

When I try

URI uri = new URI("http:///var/run/docker.sock/v1.14/");
DockerClient docker = new DefaultDockerClient(uri);

I am getting:

Exception in thread "main" com.spotify.docker.client.DockerException: com.sun.jersey.api.client.ClientHandlerException: java.lang.RuntimeException: java.lang.IllegalArgumentException: protocol = http host = null
at com.spotify.docker.client.DefaultDockerClient.propagate(DefaultDockerClient.java:577)
at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:530)
at com.spotify.docker.client.DefaultDockerClient.listContainers(DefaultDockerClient.java:180)
Caused by: com.sun.jersey.api.client.ClientHandlerException: java.lang.RuntimeException: java.lang.IllegalArgumentException: protocol = http host = null
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:155)
at com.spotify.docker.client.InterruptibleURLConnectionClientHandler$RequestTask.call(InterruptibleURLConnectionClientHandler.java:87)
at com.spotify.docker.client.InterruptibleURLConnectionClientHandler$RequestTask.call(InterruptibleURLConnectionClientHandler.java:73)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: protocol = http host = null
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1453)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439)
at sun.net.www.protocol.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:2965)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:489)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:253)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:153)
... 6 more
Caused by: java.lang.IllegalArgumentException: protocol = http host = null
at sun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:176)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1097)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:997)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:931)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1511)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
... 8 more

Is there a way to connect to my local docker instance?

Problem loading the project/testing

I just rebased to the latest version, when I run the DefaultDockerClientTest
I get the following error (on each test):
What am I doing wrong? need to open some port?

com.spotify.docker.client.DockerException: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: org.newsclub.net.unix.AFUNIXSocketException: Permission denied (socket: /run/docker.sock)
at com.spotify.docker.client.DefaultDockerClient.propagate(DefaultDockerClient.java:774)
at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:701)
at com.spotify.docker.client.DefaultDockerClient.listContainers(DefaultDockerClient.java:247)
at com.spotify.docker.client.DefaultDockerClientTest.tearDown(DefaultDockerClientTest.java:176)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: org.newsclub.net.unix.AFUNIXSocketException: Permission denied (socket: /run/docker.sock)
at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture$Sync.getValue(AbstractFuture.java:306)
at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture$Sync.get(AbstractFuture.java:293)
at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:116)
at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:699)
... 29 more
Caused by: javax.ws.rs.ProcessingException: org.newsclub.net.unix.AFUNIXSocketException: Permission denied (socket: /run/docker.sock)
at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:517)
at org.glassfish.jersey.apache.connector.ApacheConnector$1.run(ApacheConnector.java:527)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at jersey.repackaged.com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:293)
at jersey.repackaged.com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:49)
at jersey.repackaged.com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:45)
at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:523)
at org.glassfish.jersey.client.ClientRuntime$1.run(ClientRuntime.java:169)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:320)
at org.glassfish.jersey.client.ClientRuntime$2.run(ClientRuntime.java:201)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.newsclub.net.unix.AFUNIXSocketException: Permission denied (socket: /run/docker.sock)
at org.newsclub.net.unix.NativeUnixSocket.connect(Native Method)
at org.newsclub.net.unix.AFUNIXSocketImpl.connect(AFUNIXSocketImpl.java:134)
at org.newsclub.net.unix.AFUNIXSocket.connect(AFUNIXSocket.java:97)
at com.spotify.docker.client.ApacheUnixSocket.connect(ApacheUnixSocket.java:66)
at com.spotify.docker.client.UnixConnectionSocketFactory.connectSocket(UnixConnectionSocketFactory.java:77)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:123)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:318)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:469)
... 20 more

Do the docker-client suport Paging query?

Do the docker-client suport Paging query? how to do that? wating for help?
How to use "public List listImages(ListImagesParam... params) " to do Paging query? Thanks in advance!

Any way to get client logging messages on failure?

I am using docker-client as the underlying support for Eclipse plug-ins and everything is working well. When a problem occurs, however, all I am seeing in the DockerException message is that error X has occurred (e.g. 500). Sometimes, the code can be very vague in meaning. I have noticed that the client when run from the command line on Linux will issue some nice verbose messages in the lines of: Container xxxxxx cannot be paused as it is not running

Is there some way to get these verbose explanations to pass back to the end-user?

Question on keeping a docker up and running

I think I'm missing something here.
final HostConfig hostConfig = HostConfig.builder()
.networkMode("host")
.binds("/etc:/etc")
.privileged(Boolean.TRUE)
.build();

final ContainerConfig config = ContainerConfig.builder()
.image("ubuntu:latest")
.cmd("/bin/bash")
.hostname("mon-1")
.build();
final ContainerCreation creation = dockerClient.createContainer(config);
final String id = creation.id();
dockerClient.startContainer(id, hostConfig);
When I run a container with this code it seems to start up and then exit immediately. Do you know how to set interactive mode or detach?

Win7 support for Docker v1.6 & API 1.18?

Im not sure if this is the right place to post this but I can't find anywhere else, so here goes:

I ran the Boot2Docker Windows installer on Win7 64 bit. I can run docker commands just fine. Then I pulled the latest Docker-client master branch (v2.7.22) and ran it in Eclipse Java IDE. In DefaultDockerClient I changed DEFAULT_HOST and DEFAULT_PORT to the values which Docker seemed to be using https://docs.docker.com/installation/images/windows-boot2docker-cmd.png (the default values were giving me localhost:2375 connection refused errors).

I tried running the following commands:

final DockerClient docker = DefaultDockerClient.fromEnv().build();
List<ImageSearchResult> results = docker.searchImages("ubuntu");

My result is an Apache error going:

Exception in thread "main" com.spotify.docker.client.DockerException: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: org.apache.http.client.ClientProtocolException
    at com.spotify.docker.client.DefaultDockerClient.propagate(DefaultDockerClient.java:1109)
    at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:1028)
    at com.spotify.docker.client.DefaultDockerClient.searchImages(DefaultDockerClient.java:653)
    at com.spotify.docker.client.main.Test.main(Test.java:28)
Caused by: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: org.apache.http.client.ClientProtocolException
    at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture$Sync.getValue(AbstractFuture.java:306)
    at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture$Sync.get(AbstractFuture.java:293)
    at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:116)
    at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:1026)
    ... 2 more
Caused by: javax.ws.rs.ProcessingException: org.apache.http.client.ClientProtocolException
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:517)
    at org.glassfish.jersey.apache.connector.ApacheConnector$1.run(ApacheConnector.java:527)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at jersey.repackaged.com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:293)
    at jersey.repackaged.com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:49)
    at jersey.repackaged.com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:45)
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:523)
    at org.glassfish.jersey.client.ClientRuntime$1.run(ClientRuntime.java:169)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:320)
    at org.glassfish.jersey.client.ClientRuntime$2.run(ClientRuntime.java:201)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.http.client.ClientProtocolException
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:469)
    ... 20 more
Caused by: org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:151)
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:260)
    at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:161)
    at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:153)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:271)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:254)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    ... 22 more

I also tried it using the v2.7.21 client version but I had the same errors. Any ideas how to solve and is it even possible to work from a Win7 environment? Thanks!

Usage example of dockerClient.logs()

Im having trouble reading the logs from a running container via:

    @Test
    public void testLog() throws Exception {
        try (DockerClient dockerClient = DefaultDockerClient.builder().uri("http://localhost:4243").build()) {
            try (LogStream logStream = dockerClient.logs(
                    "89622a6d0b8b",
                    LogsParameter.FOLLOW,
                    LogsParameter.STDERR,
                    LogsParameter.STDOUT)) {

                LogStreamInputStream result = new LogStreamInputStream(logStream);
                final InputStreamReader inr = new InputStreamReader(result);
                String log = CharStreams.toString(inr);
                System.out.println("Log: " + log);
            }
        } catch (DockerException e) {
            e.printStackTrace();
        }
    }

    static class LogStreamInputStream extends InputStream {

        private final LogStream logStream;
        private ByteBuffer currentBuffer = null;

        /**
         * @param logStream
         */
        public LogStreamInputStream(final LogStream logStream) {
            super();
            this.logStream = logStream;
        }

        @Override
        public int read() throws IOException {
            if (this.currentBuffer == null) {
                if (this.logStream.hasNext()) {
                    this.currentBuffer = this.logStream.next().content();
                }
            }

            int result;
            if (this.currentBuffer.remaining() > 0) {
                result = this.currentBuffer.get();
            } else {
                this.currentBuffer = this.logStream.next().content();
                result = this.currentBuffer.get();
            }
            return result;
        }
    }

This example just stucks an never prints out any, it even does not loop in the read().
Can someone please give an simple example howto consume docker logs.

greetings
Stefan

X-Registry-Auth deprecated

As far as I can make out, the api version being called from the spotify client is V1.12

1).
In the docker server.go software the X-Registry-Auth appears to only be used prior to V1.9
as:

// This block can be removed when API versions prior to 1.9 are deprecated.
// Both headers will be parsed and sent along to the daemon, but if a non-empty
// ConfigFile is present, any value provided as an AuthConfig directly will
// be overridden. See BuildFile::CmdFrom for details.
if version.LessThan("1.9") && authEncoded != "" {

it has been superseded by X-Registry-Config

2).
Also, the structure of X-Registry-Auth appears to be this:

Username string json:"username,omitempty"
Password string json:"password,omitempty"
Auth string json:"auth"
Email string json:"email"
ServerAddress string json:"serveraddress,omitempty"

There doesn't appear to be a way of adding the "auth" element to the spotify client

3).
The /build element of the rest api requires authentication on a private repo
I tried adding the header .header("X-Registry-Auth", authHeader(authConfig)) to the build method
but I cannot get this build to work without falling over with a 403 error - the credentials don't seem to be passed correctly

Can anyone shed any light on these?

Jersey dependency for docker-client

This is not really an issue but more of a question. I wanted to integrate the docker-client into a project that uses another HttpClient, in this case the Resteasy client. I ran into some problems because the DefaultDockerClient was dependent on the Jersey Client. I was wondering if it maybe was possible to write this more generic against the HttpClient interfaces or if it would be an idea to move the HttpClient providing logic out of the DefaultDockerClient, so that the remaining parts can be reused for implementations with other clients. I'd like to hear you thoughts on this. ๐Ÿ˜„

Edit:
A small update on this thread: I've managed to get the tests to pass on a Resteasy client, but it involved quite a lot of work, mostly due to Resteasy only working with an older HTTP client. For the ones interested in the changes, this is the commit, which also has some comments attached.

Syntax for portSpecs

Can someone provide an example of how to build a ContainerConfig that contains port bindings, e.g.
container port 8080 bound to host port 80 ?

Usage of jnr-unixsocket for unix socket support

I would like to propose changing docker-client's unix socket support from using unix-socket-factory (junix-socket) to jnr-unixsocket [1]. The latter is more actively developed and also used in JRuby.

Currently it seems docker-client requires de.gesellix:unix-socket-factory but only uses a single bundled class (org.newsclub.net.unix.AFUNIXSocket) from junixsocket (likely since this provides the classes through a mavenized resource). The version that is bundled is listed as 1.4 [2], but the project's latest release was 1.3 [3] so it's unclear how to reproduce it.

NOTE: There are some additional changes that I would need to propose and push into jnr-unixsocket to support some necessary socket options. Once they're completed, I could create a pull request.

The changes can be found at :
https://github.com/rgrunber/docker-client
https://github.com/rgrunber/jnr-unixsocket

[1] https://github.com/jnr/jnr-unixsocket
[2] https://github.com/gesellix/unix-socket-factory/tree/master/libs
[3] https://code.google.com/p/junixsocket/

Mounted volumes

Good evening,

I use the client to start docker containers on my local machine.
All is fine excepted the volume mount.

I tried since this morning to get the same result as docker cmd: -v $HOME/.roq:/lib/RoQ/roq-config
but I didn't found the good way to do it.

Can you introduce me to the way to mount volume with the client ?

Thank you,
Benjamin

Could you explain for List Images using filters?

I wrote as referenced "public List listImages(ListImagesParam... params)" functions of DefaultDockerClient.java, I show the code as below :
Could you explain what kind of filter is it?

    final Map<String, String> filters =  newHashMap();
    filters.put("RepoTags", "nginx");

    final StringWriter writer = new StringWriter();

    try {
        final JsonGenerator generator = ObjectMapperProvider.objectMapper().getFactory().createGenerator(writer);
        generator.writeStartObject();
        for (Map.Entry<String, String> entry : filters.entrySet()) {
            generator.writeArrayFieldStart(entry.getKey());
            generator.writeString(entry.getValue());
            generator.writeEndArray();
        }
        generator.writeEndObject();
        generator.close();

        final String encoded = URLEncoder.encode(writer.toString(), UTF_8.name());

        ResponseResult result = WS2.get(dockerHost + "/images/json?filters=" + encoded);

==> It has error messages from Docker host.
statusCode":500,"statusText":"Internal Server Error"}
[debug] application - get:http://172.17.8.101:2375/images/json?filters=%7B%22repo%22%3A%5B%22nginx%3Alatest%22%5D%7D
[debug] application - 500:Internal Server Error
[debug] application - Invalid filter 'repo'

Remove 2 containers left behind by tests

This tearDown tries to kill and remove containers, but I see a couple left behind after mvn test.

docker ps -a

CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS               NAMES
b756f4b4b425        5f2915072e98                "/bin/sh -c '#(nop)    2 minutes ago                                               boring_engelbart
b9b27a0d6cb8        busybox:buildroot-2014.02   "/bin/sh -c '#(nop)    2 minutes ago                                               compassionate_mcclintock
e4e9353b3318        4197a31d4ab5                "/bin/sh -c '#(nop)    6 minutes ago                                               stupefied_kirch
5a412012f886        busybox:buildroot-2014.02   "/bin/sh -c '#(nop)    6 minutes ago                                               romantic_euclid
6d6f65b87f46        d18e2986576e                "/bin/sh -c '#(nop)    9 minutes ago                                               jolly_feynman
c78758f8b561        busybox:buildroot-2014.02   "/bin/sh -c '#(nop)    9 minutes ago                                               jolly_bell

there no method for docker stats?

there no method for docker stats?
why?
Get container stats based on resource usage
GET /containers/(id)/stats

This endpoint returns a live stream of a container's resource usage statistics.

startContainer() (and probably others) swallows errors

In commit e5efce9 the JAX-RS invocation code in DefaultDockerClient was changed to use async() and then blocking with get() on the Future. I don't know why you would enable asynchronous processing and immediately block, but I think this code swallows errors.

This call should fail but runs successfully in 2.7.5:

new DefaultDockerClient(someUri).startContainer("doesnt_exist");

The reason is in DefaultDockerClient:

  private void request(final String method,
                       final WebTarget resource,
                       final Invocation.Builder request,
                       final Entity<?> entity)
      throws DockerException, InterruptedException {
    try {
      request.async().method(method, entity).get();
    } catch (ExecutionException | MultiException e) {
      throw propagate(method, resource, e);
    }
  }

The response returned by the Future is:

InboundJaxrsResponse{ClientResponse{method=POST, uri=someUri/v1.12/containers/doesnt_exist/start, status=500, reason=Internal Server Error}}

This response is completely ignored, shouldn't this be handled and propagate some kind of exception?

Passing credentials to "push"

I am playing with the spotify docker-client (via the maven plugin). I would like to be able to specify credentials when I "push". I would be quite happy to add this myself. Is there a preferred impl path. The simplest choices I see:

  1. add top level configuration properties user id/password to the docker client
  2. add user id/password as parameters to the existing (but optional) parameters to existing "push" overloads
  3. add new "push" overloads that accept user id/password as parameters

I am guessing (3) is preferable but would like confirmation that this is acceptable before spending the time.

startContainer not using HostConfig - fails to configure port bindings, etc.

This has been baffling me for days now, so I finally have a failing test for which I have no idea why it fails.

You can add this to DefaultDockerClientTest.java and run it (I tested it against the c625fd5b commit, using HTTP not the socket, to confirm that it still fails).

  @Test
  public void testHostConfigProcessedCorrectly() throws Exception {
    sut.pull("rohan/memcached-mini");
    final ContainerConfig config = ContainerConfig.builder()
        .image("rohan/memcached-mini")
        .build();
    final ContainerCreation container = sut.createContainer(config, randomName());

    final List<PortBinding> portBindingList = 
        ImmutableList.of(PortBinding.of("", 31000));
    final Map<String, List<PortBinding>> portBindingMap = 
        ImmutableMap.of("8080/tcp", portBindingList);
    final HostConfig hostConfig = HostConfig.builder()
        .binds("/host/storage:/container/storage", "/tmp:/tmp")
        .portBindings(portBindingMap)
        .build();

    sut.startContainer(container.id(), hostConfig);

    final ContainerInfo containerInfo = sut.inspectContainer(container.id());
    assertThat(containerInfo, notNullValue());
    assertThat(containerInfo.networkSettings().ports(), 
        hasEntry("8080/tcp", portBindingList));
    assertThat(containerInfo.volumes(), 
        hasEntry("/container/storage", "/host/storage"));
    assertThat(containerInfo.volumesRW(), 
        hasEntry("/container/storage", true));
  }

It will fail because it seems like the hostConfig isn't being properly processed by Docker. I examined the JSON that it sends, which looks like this:

{"Binds":["/host/storage:/container/storage","/tmp:/tmp"],"PortBindings":{"8080/tcp":[{"HostIp":"","HostPort":"31000"}]}}

and if I send that directly to Docker, it works fine.

I then forced the test to use a Client that didn't use the interruptible handler, and it works. Here's the modified test that passes on my machine:

  @Test
  public void testHostConfigProcessedCorrectly() throws Exception {
    sut.pull("rohan/memcached-mini");
    final ContainerConfig config = ContainerConfig.builder()
        .image("rohan/memcached-mini")
        .build();
    final ContainerCreation container = sut.createContainer(config, randomName());

    final List<PortBinding> portBindingList = 
        ImmutableList.of(PortBinding.of("", 31000));
    final Map<String, List<PortBinding>> portBindingMap = 
        ImmutableMap.of("8080/tcp", portBindingList);
    final HostConfig hostConfig = HostConfig.builder()
        .binds("/host/storage:/container/storage", "/tmp:/tmp")
        .portBindings(portBindingMap)
        .build();

    URI dockerUri = URI.create(DOCKER_ENDPOINT);
    Client client = Client.create(new DefaultClientConfig(
        ObjectMapperProvider.class,
        LogsResponseReader.class,
        ProgressResponseReader.class));

    client.resource(dockerUri)
        .path("containers").path(container.id()).path("start")
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .type(MediaType.APPLICATION_JSON_TYPE)
        .entity(hostConfig)
        .post();

    final ContainerInfo containerInfo = sut.inspectContainer(container.id());
    assertThat(containerInfo, notNullValue());
    assertThat(containerInfo.networkSettings().ports(), 
        hasEntry("8080/tcp", portBindingList));
    assertThat(containerInfo.volumes(), 
        hasEntry("/container/storage", "/host/storage"));
    assertThat(containerInfo.volumesRW(), 
        hasEntry("/container/storage", true));
  }

I've tried to trace through the code, and I don't see any obvious reason for this to not work, but I did note the lack of tests in this area, so perhaps there's a problem that's not been noticed?

Using Netty instead of Jersey Client

Are you guys considering using Netty instead of Jersey Client? We have a docker client built on top of RxNetty [1], but I am looking to use a client which has more community behind it to keep up with every new docker api changes etc :) So I am considering to use this client. We use docker client from a Mesos executor which needs to be very light weight and not consume a lot of memory or spawn a lot of threads etc.

[1] https://github.com/ReactiveX/RxNetty

Ports details as in Docker ps

I'm writing an Eclipse plugin for Docker using this library but I had to modify slightly the Container class to provide the port info the way the docker ps does:

6379/tcp or 1337/tcp, 7474/tcp or 0.0.0.0:5432->5432/tcp

Do you think you would be interested on merging the change? is a public method Container.portsAsString() that returns a String with the ports info.

I haven't found the way of pulling all the ports data out of your Container class, hence this change ๐Ÿ˜„

5cbd1afe557f593710139975ca3b7280

Can't find a way to retrieve Docker Host from DockerClient

When using DefaultDockerClient.fromEnv (which is a great feature), I can't find any way to retrieve the computed Host IP from DockerClient object.
It's unfortunate because it's computed in fromEnv method.
Is there something i'm missing ?
If not, would you accept a PR for this ?

Release not-shaded artifacts

Hi,

First of all - I love your library :) . Really good job!

I'm concerned about one thing. Having JAX-RS API shaded into docker-client is usually fine, but in some cases may be problematic and leads to java.lang.LinkageError. The usual solution for such java.lang.LinkageError is to exclude JAX-RS jar from the project and leave only code shaded within the docker-client jar. But if docker-client is an Maven-optional library in your project, while some other dependency providing JAX-RS is required, then excluding JAX-RS is not really an option.

Since jars shipping shaded dependencies can be tricky (especially when shaded code perform instanceof checks, like javax.ws.rs.client.ClientBuilder#newBuilder() does), it is a good practice to release two versions of the artifacts - shaded and not-shaded. Can you guys consider releasing both shaded and not-shaded version of the library?

Cheers.

Unix sockets problem

I switched from version 2.4 to 2.7 to benefit from TLS support.

But gradle now has problems resolving dependency, it seems to be mission on maven central:
de.gesellix:unix-socket-factory:2014-09-26T18-52-33

When I try to run my code I get a runtime error:
java.lang.NoClassDefFoundError: org/newsclub/net/unix/AFUNIXSocketAddress

I do not want to use unix sockets, just http(s). Is it possible to only load unix socket related classes when needed?

Regards, Paul

Disable log printing

When executing build from command line log messages of ProgressMessage display, how can I eliminate them?

...
ProgressMessage{id=null, status=null, stream=ALTER TABLE
, error=null, progress=null, progressDetail=null}
ProgressMessage{id=null, status=null, stream= ---> a1f12f7a0cbb
, error=null, progress=null, progressDetail=null}
ProgressMessage{id=null, status=null, stream=Removing intermediate container 44d3a69dc637
, error=null, progress=null, progressDetail=null}
...

notes:
Run gradle task from command line which executes the build.
Using custom progresshandler which doesn't log or print to console.
Log is not displayed when running from eclipse.
TIA

ApacheUnixSocket throws Unimplemented instead of calling appropriate JNR-unixsocket methods

I'm running arch linux and I'm unable to get the example working. I'm using docker version:
Docker version 1.5.0, build a8a31ef

URI uri = URI.create(DefaultDockerClient.DEFAULT_UNIX_ENDPOINT);
DockerClient dockerClient = DefaultDockerClient.builder().uri(uri).build();

LOG.info("Ping: " + dockerClient.ping());

It seems to ignore this URI that I give it and tries to connect to localhost:80

[jersey-client-async-executor-0] DEBUG org.apache.http.impl.execchain.MainClientExec - Opening connection {}->unix://localhost:80
[jersey-client-async-executor-0] DEBUG org.apache.http.impl.conn.HttpClientConnectionOperator - Connecting to localhost/127.0.0.1:80
[jersey-client-async-executor-0] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: Shutdown connection
[jersey-client-async-executor-0] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection discarded
[jersey-client-async-executor-0] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: Close connection
[jersey-client-async-executor-0] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {}->unix://localhost:80][total kept alive: 0; route allocated: 0 of 100; total allocated: 0 of 100]

Then it fails with this:

com.spotify.docker.client.DockerException: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: java.lang.UnsupportedOperationException: Unimplemented

Any insights? I went deep with the debugger but couldn't figure out why this was happening.

Bind mount volumes

I'm trying to figure out how to bind mount volumes via the API. It seems that volumes is just a set of strings, rather than a map. Normally on the CLI you'd do something like "-v /source/dir:/dest/dir", but this format does not work, and slurps the entire string in as the source.

API for monitoring Docker events

Does this client provide an API to monitor docker events? If not, I think we could do an efficient implementation with disruptor, where the user supplies the client with an event handler and on receiving an event from docker the client invokes the hander.

No more loopback devices available when running tests

testSsl fails for me all the time run I run all of DefaultDockerClientTest but not when I run testSsl by itself. docker logs on the testSsl container showed that there were no more loopback devices available.

Mac OS X 10.10, boot2docker 1.3.2, docker 1.3.2

time="2014-12-23T02:41:39Z" level="info" msg="+job serveapi(tcp://0.0.0.0:2376)"
time="2014-12-23T02:41:39Z" level="error" msg="There are no more loopback devices available."
time="2014-12-23T02:41:39Z" level="fatal" msg="loopback mounting failed"

Unpack Docker Image Enhancement

I wrote some code to take a docker saved tar file and unpack it into the docker directories. This allows an saved image to be unpacked without a running docker daemon. If interested I'll submit a pull request. Otherwise I might just throw it up on my github for whomever that is interested.

Can not work on boot2docker 1.6 ?

i try to run with above code

DockerClient docker = DefaultDockerClient.fromEnv().build();
System.out.println(docker.info());

version is 2.7.21

==Exception

Exception in thread "main" com.spotify.docker.client.DockerTimeoutException: Timeout: GET http://192.168.59.103:2375/v1.12/containers/json
    at com.spotify.docker.client.DefaultDockerClient.propagate(DefaultDockerClient.java:1104)
    at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:1028)
    at com.spotify.docker.client.DefaultDockerClient.listContainers(DefaultDockerClient.java:311)
    at as.leap.cloudcode.manager.impl.TestDockerClient.main(TestDockerClient.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: java.net.SocketTimeoutException: Read timed out
    at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture$Sync.getValue(AbstractFuture.java:306)
    at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture$Sync.get(AbstractFuture.java:293)
    at jersey.repackaged.com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:116)
    at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:1026)
    ... 7 more
Caused by: javax.ws.rs.ProcessingException: java.net.SocketTimeoutException: Read timed out
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:517)
    at org.glassfish.jersey.apache.connector.ApacheConnector$1.run(ApacheConnector.java:527)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at jersey.repackaged.com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:293)
    at jersey.repackaged.com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:49)
    at jersey.repackaged.com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:45)
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:523)
    at org.glassfish.jersey.client.ClientRuntime$1.run(ClientRuntime.java:169)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:320)
    at org.glassfish.jersey.client.ClientRuntime$2.run(ClientRuntime.java:201)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:150)
    at java.net.SocketInputStream.read(SocketInputStream.java:121)
    at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:136)
    at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:152)
    at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:270)
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:260)
    at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:161)
    at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:153)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:271)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:254)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:469)
    ... 20 more

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.