Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if application has started inside container

Tags:

docker

We have an integration test suite that starts containers before starting any test cases. we used to wait for port to be available before executing any tests, which indicated that application is ready to receive requests. But with version 1.7.1 ports are instantly available, before application has even started inside container.

Is there an option to postpone docker port forwarding until port is open inside container?

Or is there other reliable method to check if application has started inside container?

like image 210
aisbaa Avatar asked Aug 05 '15 15:08

aisbaa


People also ask

How do I know if a process is running inside a container?

Like it was mentioned, if you are already inside of a container, then just use ps -eaf command to see the running processes. By the way, it is recommended to have one user application / process per container.

How do I know if my application is running in docker container?

If some of the lines start with /docker or /lxc, the process is running inside the docker or LXC container. They'll start with only / if the process runs in a host operating system. The control group is a Linux kernel feature to control or track resource usage for a group of processes.

Can you see the processes running inside a container from the outside?

Yes this is quite normal, the pid inside the container, or, atleast the MAIN pid will always be 1. But since docker uses the kernel on the host, and not its own, you will see it in ps command on the host.

Can we check the container process on docker host?

You can use docker top command. This command lists all processes running within your container.


1 Answers

But with version 1.7.1 ports are instantly available, before application has even started inside container.

I don't think that's true -- that is, I think it depends on how you are trying to contact a port. Consider, for example, a container like this:

$ docker run -it -p 8888:80 alpine sh

Here we've set up port forward from host port 8888 to container port 80, but we haven't set up anything to listen inside the container. Trying to connect to port 8888 on localhost results in a successful connection that immediately closes:

$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

Which is exactly what you are experiencing. But if instead of localhost we use an ip address of the host, we see 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 start a web server:

/ # apk add mini_httpd
[...]  
/ # mini_httpd 
mini_httpd: started as root without requesting chroot(), warning only

Then I can successfully connect:

$ telnet 192.168.1.55 8888
Trying 192.168.1.55...
Connected to 192.168.1.55.
Escape character is '^]'.

This happens because connections via localhost are handled by the Docker userland proxy, which is bound to port 8888:

# netstat -tlnp | grep 8888
tcp6       0      0 :::8888                 :::*                    LISTEN      2809/docker-proxy   

But connections to another interface ip -- and any connection originating from another host -- will be handled by the rules in the iptables nat table:

# 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 other reliable method to check if application has started inside container?

You have a few choices:

  • Just connect to the container ip directly, rather than relying on port forwarding. E.g., in the above example the container I started was assigned address 172.17.0.138. I can just connect to that instead of a host address. It's easy to find the ip address of a docker container:

    $ docker inspect --format '{{ .NetworkSettings.IPAddress }}' my-container 172.17.0.138

  • Wait until you achieve a successful connection to your application. In this example, in which I ultimately started a web server, I could wait until curl successfully connects:

    while ! curl -sf http://localhost:8888/; do
      sleep 1
    done
    

    The -f flag tells curl to exit with an error code if it cannot successfully fetch a URL.

like image 160
larsks Avatar answered Oct 10 '22 09:10

larsks