CircleCI: Best way to verify if docker containers are responding via HTTP - shell

here is an example of part of my circle.yml how I am currently verifying if my mongodb docker container is responding to an http request, so that I can verify if the response is ok and that the server is up.
test:
override:
# RUN DOCKER CONTAINERS
# MongoDB -------------
- docker run --name MongoDB -p 27018:27018 -d mongo:3.0 mongod --port 27018 --replSet "rs"; sleep 10
- curl --retry 10 --retry-delay 5 -v http://localhost:27018
with this curl it's working fine, sometimes.
And sometimes it gives me this error:
curl --retry 10 --retry-delay 5 -v http://localhost:27018
* About to connect() to localhost port 27018 (#0)
* Trying 127.0.0.1... Connection refused
* couldn't connect to host
* Closing connection #0
How can I improve this, to make it more reliable so my tests won't sometimes pass and sometimes fail, if I rebuild the same build?
note: this question was also asked on discuss.circleci.com

Related

Docker issue during gatling performance test

I have a spring boot application, and I run a performance test on it, using Gatling.
The issue is that after a few requests where everything works OK, the server returns connection refused and no other requests are working.
Gatling log looks like this:
---- Requests ------------------------------------------------------------------
> Global (OK=14 KO=1001 )
> POST /template (OK=13 KO=938 )
> PUT /feedback (OK=1 KO=63 )
---- Errors --------------------------------------------------------------------
> j.n.ConnectException: Connection refused: no further informati 577 (57,64%)
on
> j.i.IOException: Premature close 240 (23,98%)
> j.n.c.ClosedChannelException 184 (18,38%)
When I create a manual request using curl, returns:
$ curl https://localhost:8087
curl: (7) Failed to connect to localhost port 8087: Connection refused
If I connect to docker and do the request:
$ docker exec -it web /bin/bash
root#794f9e808f14:/# curl https://localhost:8443
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html
SSL handshake failed, as expected, but this means that the server is up an running.
The port is mapped in docker:
$ docker port web
8443/tcp -> 0.0.0.0:8087
8443/tcp -> :::8087
After restart, all thing happen again.
I'm using docker on a WSL Ubuntu. Not sure if this matters too much. What can I do to make this connection more stable?

Access a host from within a Docker container on Windows

I use Docker CE for Windows on latest Windows 10 and have built an image with a
script that runs a test against a web server.
(A litmus test suite for a WebDAV server to be exact, but I think the problem
is general.)
I run the web server on a Powershell console:
> wsgidav -p 8080 -H localhost
21:04:19.107 - <13348)> wsgidav INFO : Running WsgiDAV/3.0.0a3 Cheroot/6.4.0 Python/3.6.5
21:04:19.107 - <13348)> wsgidav INFO : Serving on http://localhost:8080 ...
From another Powershell console, I run my script in a Docker container (using FROM alpine).
The script starts and tries to access the endpoint, but does not succeed:
> docker pull mar10/litmus
> docker run --rm -p 8080:8080 mar10/litmus http://gateway.docker.internal:8080
-> running `basic':
0. init.................. FAIL (connection refused by `gateway.docker.internal' port 8080: Operation timed out)
I tried so far
Using the gateway.docker.internal hostname
using -p PORT:PORT
using --net=host
restarting the docker daemon (which interestingly sometimes also was neccessary to
fix timeouts in docker pull)
different IP addresses for the web server (127.0.0.1, localhost, 0.0.0.0, local IP)
Nothing worked so far (although the failure message may be different).
Maybe I just missed a working combination of the above, or any other trick?
FWIW, I was able to solve it by building the container with the --network host option and use a real IP of the client (instead of localhost or 0.0.0.0).
Details here: https://hub.docker.com/r/mar10/docker-litmus/

Docker on Mac is running but refusing to expose port

Mac here, running Docker Community Edition Version 17.12.0-ce-mac49 (21995).
I have Dockerized a web app with a Dockerfile like so:
FROM openjdk:8
RUN mkdir /opt/myapp
ADD build/libs/myapp.jar /opt/myapp
ADD application.yml /opt/myapp
ADD logback.groovy /opt/myapp
WORKDIR /opt/myapp
EXPOSE 9200
ENTRYPOINT ["java", "-Dspring.config=.", "-jar", "myapp.jar"]
I then build that image like so:
docker build -t myapp .
I then run a container of that image like so:
docker run -it -p 9200:9200 --net="host" --env-file ~/myapp-local.env --name myapp myapp
In the console I see the app start up without any errors, and all seems to be well. Even my metrics publishes (which publish heartbeat and other health metrics every 20 seconds) are printing to the console as I would expect them to. Everything seems to be fine.
Except when I go to run a curl against my app from another terminal/session:
curl -i -H "Content-Type: application/json" -X POST -d '{"username":"heyitsme","password":"12345"}' http://localhost:9200/v1/auth/signIn
curl: (7) Failed to connect to localhost port 9200: Connection refused
Now, if this were a situation where the /v1/auth/signIn path wasn't valid, or if there was something wrong with my request entity/payload, the server would pick up on it and send an error (I assure you; as I can confirm this exact same curl works when I run the server outside of Docker as just a standalone service).
So this is definitely a situation where the curl command can't connect to localhost:9200. Again, when I run my app outside of Docker, that same curl command works perfectly, so I know my app is trying to standup on port 9200.
Any ideas as to what could be going wrong here, or how I could begin troubleshooting?
The way you run your container has 2 conflicting parts:
-p 9200:9200 says: "publish (bind) port 9200 of the container to port 9200 of the host"
--net="host" says: "use the host's networking stack"
According to Docker for Mac - Networking docs / Known limitations, use cases, and workarounds, you should only publish a port:
I want to connect to a container from the Mac
Port forwarding works for localhost; --publish, -p, or -P all work. Ports exposed from Linux are forwarded to the Mac.
Our current recommendation is to publish a port, or to connect from another container. This is what you need to do even on Linux if the container is on an overlay network, not a bridge network, as these are not routed.
The command to run the nginx webserver shown in Getting Started is an example of this.
$ docker run -d -p 80:80 --name webserver nginx
Check that your app bind to 0.0.0.0:9200 and not localhost:9200 or something similar
Problem seems to be in the network mode you are running the container.
Quick test: Login to your container and run the curl cmd there, hopefully it works. That would isolate the problem to request not being forwarded from host to container.
Try running your container on the default bridge network and test.
Refer to this blog for details on the network modes in docker
TLDR; You will need to add an IPtables entry to allow the traffic to enter your container.

Docker port mapping is failing for host network mode

Mac running Docker Version 17.12.0-ce-mac55 (23011) here.
I have a very bizarre situation with Docker that I absolutely cannot explain!
I have a Dockerized web service that runs perfectly fine outside of Docker, running off of port 9200 (so: http://localhost:9200)
I can also run several other images locally (nginx, Oracle DB) and I can access them via localhost:80 and localhost:1521 respectively
When I run the container for my Dockerized service, I see (via docker logs <containerId>) the service startup without any errors whatsoever
Despite the fact that the container is running without any errors, I absolutely cannot connect to it from my Mac host via localhost:9200
The exact steps to reproduce are:
Clone this repo
Build the image via ./gradlew clean build && docker build -t locationservice .
Run the container via docker run -it -p 9200:9200 -d --net="host" --name locationservice locationservice
If you use docker ps to obtain the <containerId>, then you can keep hitting docker logs <containerId> until you see it has started up without errors
On my machine, when I try to curl against localhost:9200, I get "connection refused" errors (see below)
curl error is:
curl -X GET http://localhost:9200/bupo
curl: (7) Failed to connect to localhost port 9200: Connection refused
Some things I have ruled out:
localhost is absolutely resolveable from the host because we're running in host network mode and I have no problem connecting to nginx (port 80) and Oracle (port 1521) containers
The app is starting up and if you look at the logs you'll see it is starting up listening on 9200
Any ideas what the problem could be?!
Docker for Mac runs in a VM. --net=host refers to the Linux VM hosts network stack not OSX. There is no direct network path from OSX to the Docker VM other than mapped ports.
Mapped ports (docker run -p Y:N) in Docker for Mac are a little special, in addition to the user space proxy that runs on the Docker host normally, Docker for Mac also launches a user space proxy on OSX to listen on the same port and forward connections into the VM. The OSX process isn't started when using --net=host (and the Linux one isn't either of course).
→ docker run --name nc --rm --net=host -dp 9200:9200 busybox nc -lk -p 9201 -e echo hey
→ docker inspect nc --format '{{ json .NetworkSettings.Ports }}'
{}
→ sudo lsof -Pni | grep 9200
→
Then without --net=host
→ docker run --name nc --rm -dp 9200:9200 busybox nc -lk -p 9201 -e echo hey
→ docker inspect nc --format '{{ json .NetworkSettings.Ports }}'
{"9200/tcp":[{"HostIp":"0.0.0.0","HostPort":"9200"}]}
→ sudo lsof -Pni | grep 9200
vpnkit 42658 matt 28u IPv4 0x57f79853269b81bf 0t0 TCP *:9200 (LISTEN)
vpnkit 42658 matt 29u IPv6 0x57f798532765ca9f 0t0 TCP [::1]:9200 (LISTEN)
If your app requires --net=host then I would use Vagrant/Virtualbox to spin up a VM with a "Host Only" adapter. This means there is a direct network path that you can access from OSX on the VM. Here's the Vagrantfile I use.
Docker for Mac does not support host network mode very well: https://github.com/docker/for-mac/issues/1031
So at this moment the solution is to use default bridge mode.

Unable to access hosted app from docker in Windows

I started to play around with docker for a while and got stuck with the below:
Here's my Environment:
Windows 10
boot2docker/Docker version 1.12.0
Virtual box 5.0.24
this is what i'm trying to do:
$ docker run -itp 8090:8090 lamp
root#8ebc390337be:/# service apache2 start
* Starting web server apache2 *
root#8ebc390337be:/# service mysql start
* Starting MySQL database server mysqld [ OK ]
root#8ebc390337be:/#
deattached from container and then
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ebc390337be lamp "/bin/bash" 13 minutes ago Up 13 minutes 0.0.0.0:8090->8090/tcp happy_brown
$ docker inspect $(docker ps -q) | grep IPA
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
now when i try to run
$ curl 172.17.0.2:8090
curl: (7) Failed to connect to 172.17.0.2 port 8090: Timed out
then i tried
$ docker-machine ip default
192.168.99.100
$ curl 192.168.99.100:8090
curl: (7) Failed to connect to 192.168.99.100 port 8090: Connection refused
i did go through this accessing-a-docker-container-url-on-windows-host but it didn't help me.
i should be able to access the url from inside and outside the docker.
Could someone help me to troubleshoot
This is the ip address you should be using 192.168.99.100
I expect the problem is that your apache server is on port 80 inside the container, not 8090, i.e. your docker command should be:
$ docker run -itp 8090:80 linode/lamp
Which means map port 8090 on the outside host (192.168.99.100) to port 80 inside the container.

Resources