I am using Locust, a performance testing tool, to load test an application that is setup to run within docker-compose. I get the following error (connection refused, error 111) for every request:
Error report
# occurrences Error
--------------------------------------------------------------------------------------------------------------------------------------------
5 GET /parties/: 'ConnectionError(MaxRetryError("HTTPConnectionPool(host=\'localhost\', port=8080): Max retries exceeded with url: /parties/ (Caused by NewConnectionError(\'<urllib3.connection.HTTPConnection object at 0x7fa6f294df28>: Failed to establish a new connection: [Errno 111] Connection refused\',))",),)'
I am running Locust from a docker container as follows:
docker run --volume /mydir/locustfile:/mnt/locust -e LOCUSTFILE_PATH=/mnt/locust/locustfile.py -e TARGET_URL=https://localhost:8080/parties -e LOCUST_OPTS="--clients=1 --no-web --run-time=600" locustio/locust
The weird thing is that when I use curl to hit the exact same URL it works properly.
curl http://localhost:8080/parties
Any help is appreciated!
localhost is probably the wrong hostname to use in your context. when you use containers, the hostname must match the container's name. so use your container's name instead of localhost.
references:
https://github.com/elastic/elasticsearch-py/issues/715
https://docs.locust.io/en/latest/running-locust-docker.html
https://docs.locust.io/en/stable/configuration.html
general assumption:
locustfile.py exists in the current working directory
a distributed example with docker compose:
for example, the following docker-compose.yml file config will work:
services:
web:
build: .
command: python manage.py runserver 0:8000
volumes:
- .:/code/
ports:
- "8000:8000"
master:
image: locustio/locust
ports:
- "8089:8089"
volumes:
- ./:/mnt/locust
command: -f /mnt/locust/locustfile.py --master -H http://web:8000
worker:
image: locustio/locust
volumes:
- ./:/mnt/locust
command: -f /mnt/locust/locustfile.py --worker --master-host master
the -H flag (alias for --host) on the following line makes the trick:
command: -f /mnt/locust/locustfile.py --master -H http://web:8000
a non-distributed example with docker compose:
services:
web:
build: .
command: python manage.py runserver 0:8000
volumes:
- .:/code/
ports:
- "8000:8000"
locust:
image: locustio/locust
ports:
- "8089:8089"
volumes:
- ./:/mnt/locust
command: -f /mnt/locust/locustfile.py --host=http://web:8000
you can also specify a config file, instead of defining the flags on the command line. supose the file locust.conf exists in the current working directory:
locust.conf:
host: http://web:8000
so in your docker-compose.yml you do:
command: -f /mnt/locust/locustfile.py --config=/mnt/locust/locust.conf
instead of:
command: -f /mnt/locust/locustfile.py --host=http://web:8000
a non-distributed example without docker compose:
the containers must live on the same network, so they can communicate with each other. to do so, let's create a common bridge network called locustnw:
docker network create --driver bridge locustnw
now run your app container within this network. Supose it's listening on port 8000 and named web:
docker run -p 8000:8000 --network=locustnw --name web <my_image>
now run your locust container, within the same network too. Supose it's listening on port 8089:
docker run -p 8089:8089 --network=locustnw -v $PWD:/mnt/locust locustio/locust -f /mnt/locust/locustfile.py --host=http://web:8000
the --network, --name and --host flags are the keys!
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