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?

+3


source to share


1 answer


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.

+6


source







All Articles