How to check if an application is running inside a container
We have an integration test suite that runs containers before any test cases start. we expected the port to be available before doing any tests, which indicates that the application is ready to receive requests. But with version 1.7.1 ports are instantly available before the application even runs inside the container.
Is there an option to postpone porting the docker port until the port is open inside the container?
Or is there another reliable method for verifying that an application is running inside a container?
source to share
But with version 1.7.1 ports are instantly available before the application even runs inside the container.
I don't think this is true, that is, I guess it depends on how you are trying to communicate with the port. Consider for example a container like this:
$ docker run -it -p 8888:80 alpine sh
Here we have configured the forward port from host port 8888 to container port 80, but we have not configured anything to listen inside the container. An attempt to connect to port 8888 localhost
results in a successful connection, which is closed immediately:
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
This is exactly what you are experiencing. But if localhost
we use the host ip instead , we see a different behavior:
$ telnet 192.168.1.55 8888
Trying 192.168.1.55...
telnet: connect to address 192.168.1.55: Connection refused
If inside the container I run a web server:
/ # apk add mini_httpd
[...]
/ # mini_httpd
mini_httpd: started as root without requesting chroot(), warning only
Then I can connect successfully:
$ telnet 192.168.1.55 8888
Trying 192.168.1.55...
Connected to 192.168.1.55.
Escape character is '^]'.
This is because connections through are localhost
handled by the Docker userland proxy that is bound to port 8888:
# netstat -tlnp | grep 8888
tcp6 0 0 :::8888 :::* LISTEN 2809/docker-proxy
But connections to a different ip interface - and any connection originating from another host will be handled by the rules in the iptables table nat
:
# iptables -t nat -S DOCKER
-N DOCKER
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8888 -j DNAT --to-destination 172.17.0.138:80
Or is there another reliable method for verifying that an application is running inside a container?
You have several options:
-
Just connect to the ip container directly instead of relying on port forwarding. For example, in the example above, the initial container was assigned the address 172.17.0.138. I can just connect to it instead of the host address. It's easy to find the ip address of the docker container:
$ docker inspect --format '{{.NetworkSettings.IPAddress}}' my-container 172.17.0.138
-
Wait until you achieve a successful connection with your application. In this example, when I eventually started the web server, I could wait for
curl
it to connect successfully:while ! curl -sf http://localhost:8888/; do sleep 1 done
The flag
-f
tells curl to exit with an error code if it cannot successfully get the url.
source to share