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.