docker-maven-plugin icon indicating copy to clipboard operation
docker-maven-plugin copied to clipboard

Remote docker-host and non-SSL-setup

Open jarmoni opened this issue 8 years ago • 28 comments

I exported environment-variable DOCKER_HOST as described (Port 2375 -> no SSL):

➜  ~  echo $DOCKER_HOST
tcp://192.168.33.10:2375
➜  ~

This worked for months in version 0.2.11 but in 0.4.0 it seems to be broken. The plugin tries to connect via SSL and this (of course) fails:

[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:0.4.0:build (default) on project service-cache: Exception caught: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection? -> [Help 1]

When I set config-property 'dockerHost' in the plugin's config <dockerHost>tcp://192.168.33.10:2375</dockerHost>, I get:

[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:0.4.0:build (default) on project service-cache: Exception caught: An HTTPS URI for DOCKER_HOST must be provided to use Docker client certificates -> [Help 1]

There are no additional env-variables like DOCKER_CERT_PATH or DOCKER_TLS_VERIFY exported in my environment. So I don't know why the plugin assumes that I use SSL

jarmoni avatar Feb 02 '16 06:02 jarmoni

Looks like the issue is that AbstractDockerMojo calls DefaultDockerClient.fromEnv() which defaults to setting a certificate path of System.getProperty("user.home") + ".docker" with no way of overriding the logic or specifying your own DefaultDockerClient.Builder.

mattnworb avatar Feb 02 '16 14:02 mattnworb

v0.3.7 seem to also have the problem. This tag doesn't exist in the github project but the Maven artifact is available. It's using docker-client v3.3.1.

It'd be nice to know what is the latest version that does't have the problem.

nodje avatar Feb 26 '16 11:02 nodje

+1

volyx avatar Mar 05 '16 22:03 volyx

To use docker:build on my local workstation with a docker daemon not using TLS, I temporarily renamed the folder "~/.docker" to "~/.docker.tmp" and used <dockerHost>unix:///var/run/docker.sock</dockerHost> in the plugin configuration.

Surprise: I got a BUILD SUCCESS!

This would confirm mattnworb 's hypothesis. Obviously not a very practical solution but an interesting result.

laurent-opnworks avatar Mar 06 '16 02:03 laurent-opnworks

@mattnworb Any workaround for this? I'm coming from #221 and #222

marcellodesales avatar Apr 18 '16 23:04 marcellodesales

@laurent-opnworks what version were you using? I tried your workaround and did not get anywhere...

marcellodesales avatar Apr 19 '16 05:04 marcellodesales

@marcellodesales I believe it was docker v1.10 and docker-maven-plugin v0.3.258 but I have not pursued my investigations since then. Still hoping/waiting for a "real" solution.

laurent-opnworks avatar Apr 19 '16 12:04 laurent-opnworks

@mattnworb How does https://github.com/spotify/docker-maven-plugin/pull/216 look as a solution? It seems pretty good to me.

davidxia avatar Apr 19 '16 13:04 davidxia

DefaultDockerClient.fromEnv() in docker-client will configure the DockerClient to use a set of certificates if the path pointed to by DOCKER_CERT_PATH or ~/.docker exists and if each of ca.pem, cert.pem and key.pem exists in that directory (see here, here and here).

@laurent-opnworks do you have files in this path even though your docker daemon does not use TLS?

mattnworb avatar Apr 20 '16 19:04 mattnworb

On the other hand, this check in docker-client doesn't really need to be there

if ((builder.dockerCertificates != null) && !originalUri.getScheme().equals("https")) {
  throw new IllegalArgumentException(
      "An HTTPS URI for DOCKER_HOST must be provided to use Docker client certificates");
}

as the class takes care elsewhere not to assume that builder.dockerCertificates is non-null if the URI is https.

mattnworb avatar Apr 20 '16 19:04 mattnworb

Sorry, my previous comment is false. DefaultDockerClient uses the presence of the DockerCertificates class to determine if it should use http or https to communicate with the Docker Remote API to talk to the daemon (when the DOCKER_HOST or .dockerHost(..) values does not start with unix://).

This seems like a fair assumption to make since the DOCKER_HOST format generally starts with tcp:// regardless of whether or not TLS is used.

Another way for the DefaultDockerClient to tell if it should use https or http could be to look at the port portion of the URI in DOCKER_HOST, since conventionally 2375 is for non-TLS and 2376 is for TLS connections; however, since you could in theory configure your daemon to use any port you want whether or not TLS is enabled, this seems like it would be a worse condition to base logic off of.

It might make more sense to add a flag like boolean tlsEnabled to the DockerClient and to this plugin, to use in deciding to use https or http, rather than the presence of these certificate files. This is more or less how the docker CLI client and daemon work.

But for a workaround today, you could remove the certs in ~/.docker if you do not intend for the plugin to use TLS.

mattnworb avatar Apr 20 '16 20:04 mattnworb

@mattnworb I'm thinking how this would work in a CI server... Changing the ~/.docker directory may affect other docker calls in the host, right? That just doesn't sound that great... I agree with your assessment in regards to the boolean tlsEnabled, since it indicates the true desire of the plugin's user.

marcellodesales avatar Apr 26 '16 14:04 marcellodesales

Any progress on this? Setting docker server to HTTP doesn't seem like a legitimate "solution". Why can't the client connect to the unix socket as configured? I happen to be working in an environment where changing the docker server is not a long time solution.

NorrinRadd avatar Oct 04 '17 18:10 NorrinRadd

I have the same issue of "com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection? " Any idea how to fix?

sherryhw avatar Oct 05 '17 19:10 sherryhw

Ensure that directory ~/.docker does not exist.

jarmoni avatar Oct 05 '17 20:10 jarmoni

@jarmoni hey why the /.docker folder should not exist? And even after i delete this folder, there are some other issues like "Caused by: java.net.SocketException: Connection reset by peer: socket write error"

Thanks!

sherryhw avatar Oct 05 '17 20:10 sherryhw

If the folder exists, the plugin assumes that you want to use SSL. Don't blame me for this behaviour, I am just the original reporter of the issue (1,5 years ago...) ;-) Your current problem seems not to be related to the SSL-thing. Maybe the following will help:

export DOCKER_HOST=tcp://<the_machine_where_your_docker_daemon_runs>:2375

and then in same terminal:

mvn ....

jarmoni avatar Oct 05 '17 21:10 jarmoni

@jarmoni Thanks for the quick reply! I have been trapped in this issue for quite a while. I also report this one here. https://github.com/spotify/dockerfile-maven/issues/80

I use docker for windows and i already set the env virables for DOCKER_HOST(DOCKER_HOST=tcp://localhost:2375) and DOCKER_CERT_PATH. If I dont have DOCKER_CERT_PATH, it will end up with "Caused by: java.net.SocketException: Connection reset by peer: socket write error". If it has DOCKER_CERT_PATH, it will end up with "javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?"

Any ideas?

sherryhw avatar Oct 05 '17 21:10 sherryhw

I'm sorry, I have no expirience with docker on Windows. On Linux the above should work.

jarmoni avatar Oct 05 '17 21:10 jarmoni

thanks! i may try on a linux system to see whether it is working!

sherryhw avatar Oct 05 '17 21:10 sherryhw

But I would assume that If you don't want to use SSL/TLS the variable DOCKER_CERT_PATH should not be set. In my environment the only docker-related env-var is:

> echo $DOCKER_HOST
tcp://localdocker1:2375

.... where localdocker1 is a Vagrant-box running on my local machine.

jarmoni avatar Oct 05 '17 21:10 jarmoni

But it is quite simple: If the common commands (docker run..., ....) work when executed in command-line, the plugin should work as well - if invoked in same shell. But as I said before: I have no experience with Windows-systems.

jarmoni avatar Oct 05 '17 21:10 jarmoni

If I dont have DOCKER_CERT_PATH, it will end up with "Caused by: java.net.SocketException: Connection reset by peer: socket write error"

This usually points to the thing you are connecting to closing the connection (sending a RST) when your client tries to establish the connection. I am not familiar at all with Docker for Windows either but you might want to doublecheck that it is actually listening on port 2375.

mattnworb avatar Oct 06 '17 11:10 mattnworb

@jarmoni Hi I can build the image through Docker using command "docker build " and can run container successfully. Only the plugin for build is not working, let alone for pushing to the repository.

@mattnworb Hi thank you for your reply! I did check the process on 2375. It is docker.proxy listening on port 2375.

#PS netstat -ano |findstr 2375 TCP 127.0.0.1:2375 0.0.0.0:0 LISTENING 9268 #PS tasklist | findstr 9268 com.docker.proxy.exe 9268 Console 1 12,896 K

Any ideas? I try to search for help in the docker for windows size but no luck. Still thank you guys for the help.

sherryhw avatar Oct 06 '17 14:10 sherryhw

@sherryhw Did you already check what happens on the network when you...

  • invoke docker-commands on the command-line
  • use the maven-plugin

In Unix-systems tcpdump is a good tool for this job. I guess there is something similar in the Windows-world.

jarmoni avatar Oct 06 '17 17:10 jarmoni

Hello everybody. I face with same error described here. I tried several solutions suggested in the chat, but what I can see is

INFO: I/O exception (java.net.SocketException) caught when processing request to {}->http://localhost:2375: Connection reset by peer: socket write error

So it is strange error because I really use echo %DOCKER_HOST% tcp://localhost:2375

So in my understanding it should try to reach tcp instead of http?

smuryginim avatar Mar 01 '18 15:03 smuryginim

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Sep 11 '18 13:09 stale[bot]

But I would assume that If you don't want to use SSL/TLS the variable DOCKER_CERT_PATH should not be set. In my environment the only docker-related env-var is:

> echo $DOCKER_HOST
tcp://localdocker1:2375

.... where localdocker1 is a Vagrant-box running on my local machine.

originally,I set-up the toolbox in my local machine,it is ok to build the image to the local docker,then I try to build images to the remote docker,it showed "Unrecognized SSL message, plaintext?" After I deleted the env-var "DOCKER_CERT_PATH",and then it works.Maybe the toolbox set some env-var about docker automatically cause this issue

KAKALZF avatar Feb 12 '20 15:02 KAKALZF