-
Notifications
You must be signed in to change notification settings - Fork 644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docker for mac beta and docker:start with wait/tcp/ports incorrectly waits on container port #430
Comments
Unfortunately I don't have acess to Docker for Mac yet, so its a bit hard to reproduce it ;-) 'hope its ok to wait until Docker for Mac is publicly available .... |
I had similar problems, but they were resolved with yesterdays update to Docker for Mac Version 1.11.0-beta9. @stephenc, perhaps your use-case works now as well? |
Finally I got my Docker-for-Mac token. @stephenc do you have a pom.xml to share so that I can reproduce the issue ? |
Using Docker: I get the following output:
The project builds just fine if I switch to |
Looking at this quickly it seems that if the host is 'localhost' and the container has an IP address then the plugin assumes that the container is reachable on that IP address (https://github.com/fabric8io/docker-maven-plugin/blob/master/src/main/java/io/fabric8/maven/docker/StartMojo.java#L192). This is not the case with my version of Docker for Mac (Version 1.12.0-rc2-beta16 (build: 9493)). I'm curious if it wouldn't be simpler to just omit the special case of localhost and an IP address. Is there in fact a case where this is used? At any rate, I've opened a pull request that does just that. |
Now that Docker for Mac is in public beta, I can verify the issue and that Docker for Mac joins the Mac's network space, so in this case I have to grab in my memories, why this fallback has been introduced. Not sure whether it ever worked as it seems that the internal IP was used (which is not accessible from the outside by this plugin). |
One interesting point I'm seeing locally is that with my pull request, I'm getting different behavior with docker for mac than I was with docker-machine. In short, with docker-machine the TCP connection failed thus the wait works. On docker for mac, the connection actually succeeds but then is closed immediately by the remote (but not before we pass the check). In particular, I'm seeing this with the following configuration:
I've not done a lot of trouble shooting here, but I'm moving to a log based wait in the mean time. |
Now that I had a closer look, the issue we had already as described in #304 . Waiting on a TCP ports works by trying to open a connections on the port. Docker maps the internal container ports to ports on the Docker daemon's host. However, Docker uses by default a so called user-proxy which opens these port immediately even when they are not reachable on the container. So a connect always works on the very beginning. That was also the reason why this localhost hack was introduced. (see #304 for details). It seems now that Docker for Mac doesnt use user proxy of works differently in general. I still need to dig a bit deeper to find a proper solution. |
@stephenc @joshua-rutherford had the chance to refresh my memory again with respect to the issue #304 and in particular with the Docker user-proxy used for port mapping (as described in moby/moby#14856). There are two modes how you can access a Docker daemon: Either via Unix socket on Linux system (and now with Docker for Mac) other via remote HTTP. When using a Docker daemon via HTTP over TCP then everything is fine: The ports get connected via the external IP and the mapped ports. However when using a unix socket, the port mapping works that there will be a proxy started when a container is started which immediately opens the mapped ports and proxies these to the container ports. This means that in this case a wait check will return immediately, even when the the container is not ready. On a linux system you can however access the container IP directly (via the Docker bridge) and which gets routed, so that you can access the original (so, non mapped ports) with the check. Thats was the 'localhost' mode mentioned by @joshua-rutherford Now for Docker for Mac the container IP is not routed anymore so that the solution above does not work anymore ;-( Unfortunately the user proxy is still the default mode (however it was to supposed to be switched off by default for quite some time). I introduced now a tcp 'mode' which can
Currently I dont see a good solution ;-( Any ideas ? |
Can bei either "mapped" which uses a remote Docker IP and mapped ports or "direct" where the container is contacted directly with the unmapped ports (needed to avoid issues with the user-proxy of Docker daemons which are enabled by default). "mapped" is the default when host is not "localhost", "direct" when host is "localhost".
Hi Some of my coworkers have the same issue. Do you have any update ? Cheers |
Sorry, I'm not aware for a workaround. Haven't check the upstream development recently, though. So maybe it could be possible that the container IP is directly accessible nowadays. But not really sure, and probably not the case (since its still running in a VM). A solution could be to configure Docker for Mac to be accessed via TCP, but I don't know whether this is possible. Remember, when accessing the Docker daemon via TCP there is no problem at all. Yet another idea is to support the new Docker health checks directly. Tbh didn't yet looked into it. I'm open for any ideas to solve this. |
@aromanet42 The "workaround" is to have a docker machine like before version 1.12 if you want to still use 1.12 and this plugin at the same time. |
I found that in most cases I could wait on a log message that announced the port binding instead of hitting the port directly. |
Indeed, waiting on a log message work for us as well. Thanks :) |
Any update on this? Waiting on log message doesn't work for MySQL as the server is actually not ready to serve the requests, by the time log is printed. |
Hi! Any news/workarounds for this? |
@ol2ka , sure, just remove these tags <wait>
<tcp>
<ports>
<port> |
I for one haven't had to use another work around, but reviewing the documentation. You could configure a health check that is more robust than just establishing an ephemeral connection and wait on that with the Haven't looked at this, just tossing it out as an idea. |
The following seems to do the trick for me:
|
I ended up putting the following shell script as "/mysql/wait.sh" into my Maven project
Then setting like this:
It seems to be working for me. Here's working example: https://github.com/nuzayats/junit5examples/blob/master/pom.xml |
I have had so many issues with images that do not have proper health checks that I just have developed the habit of ensuring they have a proper healthcheck. As a result I can bypass this issue by just waiting for the image to be healthy... though that does sometimes require (if the image connects to others) that I make the downstream images retry failed connections - but you'd want your images to do that anyway |
Closing as likely an upstream issue with docker and not much this plugin can do about it |
Running a maven project that uses the wait/tcp/ports functionality to wait for the container to listen on a specific port:
Observed results:
With docker-machine, the logs output
With docker for mac beta:
Expected results:
Build should pass with either docker-machine or docker for mac
Preliminary analysis:
Something seems to be going wrong in the detection of whether the container is directly accessible.
The text was updated successfully, but these errors were encountered: