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 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.
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.
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.
You can use docker top command. This command lists all processes running within your container.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With