Docker, Django and Selenium - Selenium unable to connect Docker, Django and Selenium - Selenium unable to connect selenium selenium

Docker, Django and Selenium - Selenium unable to connect


I ended up coming up with a better solution that didn't require me to hardcode the IP Address. Below is the configuration I used to run tests in django with docker.

Docker-compose file

# docker-compose base file for everythingversion: '2'services:  postgis:    build:      context: .      dockerfile: ./docker/postgis/Dockerfile    container_name: postgis    volumes:      # If you are using boot2docker, postgres data has to live in the VM for now until #581 fixed      # for more info see here: https://github.com/boot2docker/boot2docker/issues/581      - /data/dev/docker_cookiecutter/postgres:/var/lib/postgresql/data  django:    build:      context: .      dockerfile: ./docker/django/Dockerfile    container_name: django    volumes:      - .:/app    depends_on:      - selenium      - postgis    environment:      - SITE_DOMAIN=django      - DJANGO_SETTINGS_MODULE=settings.my_dev_settings    links:      - postgis      - mailcatcher  selenium:    container_name: selenium    image: selenium/standalone-firefox-debug:2.52.0    ports:      - "4444:4444"      - "5900:5900"

Dockerfile (for Django)

ENTRYPOINT ["/docker/django/entrypoint.sh"]

In Entrypoint file

#!/bin/bashset -e# Now we need to get the ip address of this container so we can supply it as an environmental# variable for django so that selenium knows what url the test server is on# Use below or alternatively you could have used# something like "$@ --liveserver=$THIS_DOCKER_CONTAINER_TEST_SERVER"if [[ "'$*'" == *"manage.py test"* ]]  # only add if 'manage.py test' in the argsthen  # get the container id  THIS_CONTAINER_ID_LONG=`cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1`  # take the first 12 characters - that is the format used in /etc/hosts  THIS_CONTAINER_ID_SHORT=${THIS_CONTAINER_ID_LONG:0:12}  # search /etc/hosts for the line with the ip address which will look like this:  #     172.18.0.4    8886629d38e6  THIS_DOCKER_CONTAINER_IP_LINE=`cat /etc/hosts | grep $THIS_CONTAINER_ID_SHORT`  # take the ip address from this  THIS_DOCKER_CONTAINER_IP=`(echo $THIS_DOCKER_CONTAINER_IP_LINE | grep -o '[0-9]\+[.][0-9]\+[.][0-9]\+[.][0-9]\+')`  # add the port you want on the end  # Issues here include: django changing port if in use (I think)  # and parallel tests needing multiple ports etc.  THIS_DOCKER_CONTAINER_TEST_SERVER="$THIS_DOCKER_CONTAINER_IP:8081"  echo "this docker container test server = $THIS_DOCKER_CONTAINER_TEST_SERVER"  export DJANGO_LIVE_TEST_SERVER_ADDRESS=$THIS_DOCKER_CONTAINER_TEST_SERVERfieval "$@"

In your django settings file

SITE_DOMAIN = 'django'

Then to run your tests

docker-compose run django ./manage.py test


Whenever you see localhost, try first to port-forward that port (at the VM level)

See "Connect to a Service running inside a docker container from outside"

VBoxManage controlvm "default" natpf1 "tcp-port8081,tcp,,8081,,8081"VBoxManage controlvm "default" natpf1 "udp-port8081,udp,,8081,,8081"

(Replace default with the name of your docker-machine: see docker-machine ls)

This differs for port mapping at the docker host level (which is your boot2docker-based Linux host)

The OP luke-aus confirms in the comments:

entering the IP address for the network solved the problem!


I've been struggling with this as well, and I finally found a solution that worked for me. You can try something like this:

postgis:  dockerfile: ./docker/postgis/Dockerfile  build: .django:  dockerfile: ./docker/Dockerfile-dev  build: .  command: python /app/project/manage.py test my-app  volumes:    - .:/app  ports:    - "8000:8000"  links:    - postgis    - selenium  # django can access selenium:4444, selenium can access django:8081-8100  environment:    - SELENIUM_HOST=http://selenium:4444/wd/hub    - DJANGO_LIVE_TEST_SERVER_ADDRESS=django:8081-8100  # this gives selenium the correct addressselenium:  image: selenium/standalone-firefox-debug  ports:    - "5900:5900"

I don't think you need to include port 4444 in the selenium config. That port is exposed by default, and there's no need to map it to the host machine, since the django container can access it directly via its link to the selenium container.

[Edit] I've found you don't need to explicitly expose the 8081 port of the django container either. Also, I used a range of ports for the test server, because if tests are run in parallel, you can get an "Address already in use" error, as discussed here.