Docker、Django 和 Selenium - Selenium 无法连接
Docker, Django and Selenium - Selenium unable to connect
我使用 docker-compose.yml 将 Docker 配置为 运行 Postgres 和 Django,并且工作正常。
我遇到的问题是 Selenium 无法连接到 Django liveserver。
现在(至少对我而言)django 必须访问 selenium 来控制浏览器并且 selenium 必须访问 django 才能访问服务器是有道理的。
我已经尝试使用 docker 'ambassador' 模式,使用以下配置 docker-compose.yml 来自这里:https://github.com/docker/compose/issues/666
postgis:
dockerfile: ./docker/postgis/Dockerfile
build: .
container_name: postgis
django-ambassador:
container_name: django-ambassador
image: cpuguy83/docker-grand-ambassador
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
command: "-name django -name selenium"
django:
dockerfile: ./docker/Dockerfile-dev
build: .
command: python /app/project/manage.py test my-app
container_name: django
volumes:
- .:/app
ports:
- "8000:8000"
- "8081:8081"
links:
- postgis
- "django-ambassador:selenium"
environment:
- SELENIUM_HOST=http://selenium:4444/wd/hub
selenium:
container_name: selenium
image: selenium/standalone-firefox-debug
ports:
- "4444:4444"
- "5900:5900"
links:
- "django-ambassador:django"
当我检查时 http://DOCKER-MACHINE-IP:4444/wd/hub/static/resource/hub.html
我可以看到 firefox 启动了,但是所有测试都失败了,因为 firefox 无法连接到 django
'Firefox can't establish a connection to the server at localhost:8081'
我在这里也试过这个解决方案https://github.com/docker/compose/issues/1991
但是这不起作用,因为我无法让 django 同时连接到 postgis 和 selenium
'django.db.utils.OperationalError: could not translate host name "postgis" to address: Name or service not known'
我尝试使用下面列出的网络功能
postgis:
dockerfile: ./docker/postgis/Dockerfile
build: .
container_name: postgis
net: appnet
django:
dockerfile: ./docker/Dockerfile-dev
build: .
command: python /app/project/manage.py test foo
container_name: django
volumes:
- .:/app
ports:
- "8000:8000"
- "8081:8081"
net: appnet
environment:
- SELENIUM_HOST=http://selenium:4444/wd/hub
selenium:
container_name: selenium
image: selenium/standalone-firefox-debug
ports:
- "4444:4444"
- "5900:5900"
net: appnet
但结果是一样的
'Firefox can't establish a connection to the server at localhost:8081'
那么我怎样才能让 selenium 连接到 django?
我已经研究了好几天了 - 非常感谢任何帮助。
更多信息
另一个奇怪的事情是,当测试服务器运行宁不使用docker(使用我的virtualenv等旧配置)如果我运行 ./manage.py test foo 我可以通过 http://localhost:8081 的任何浏览器访问服务器并获得网页,但是当我 运行如果我 运行 它在 docker 下,则等效命令。这很奇怪,因为我正在映射端口 8081:8081 - 这是否相关?
注意:我使用的是 OSX 和 Docker v1.9.1
每当您看到本地主机时,首先尝试转发该端口(在 VM 级别)
参见“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"
(将 default
替换为您的 docker 机器的名称:参见 docker-machine ls
)
这与 docker 主机级别的端口映射不同(这是基于 boot2docker 的 Linux 主机)
OP luke-aus confirms :
entering the IP address for the network solved the problem!
我最终想出了一个更好的解决方案,不需要我对 IP 地址进行硬编码。下面是我用来 运行 在 django 中使用 docker.
测试的配置
Docker-编写文件
# docker-compose base file for everything
version: '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"
Docker文件(对于 Django)
ENTRYPOINT ["/docker/django/entrypoint.sh"]
在入口点文件中
#!/bin/bash
set -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 args
then
# 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_SERVER
fi
eval "$@"
在你的 django 设置文件中
SITE_DOMAIN = 'django'
然后运行你的测试
docker-compose run django ./manage.py test
我也一直在为此苦苦挣扎,我终于找到了适合我的解决方案。你可以尝试这样的事情:
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 address
selenium:
image: selenium/standalone-firefox-debug
ports:
- "5900:5900"
我认为您不需要在 selenium 配置中包含端口 4444。该端口默认公开,无需将其映射到主机,因为 django 容器可以通过其 link 直接访问它到 selenium 容器。
[编辑] 我发现您也不需要显式公开 django 容器的 8081 端口。此外,我为测试服务器使用了一系列端口,因为如果测试是 运行 并行,您可能会遇到 "Address already in use" 错误,如 here.
所述
我使用 docker-compose.yml 将 Docker 配置为 运行 Postgres 和 Django,并且工作正常。
我遇到的问题是 Selenium 无法连接到 Django liveserver。
现在(至少对我而言)django 必须访问 selenium 来控制浏览器并且 selenium 必须访问 django 才能访问服务器是有道理的。
我已经尝试使用 docker 'ambassador' 模式,使用以下配置 docker-compose.yml 来自这里:https://github.com/docker/compose/issues/666
postgis:
dockerfile: ./docker/postgis/Dockerfile
build: .
container_name: postgis
django-ambassador:
container_name: django-ambassador
image: cpuguy83/docker-grand-ambassador
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
command: "-name django -name selenium"
django:
dockerfile: ./docker/Dockerfile-dev
build: .
command: python /app/project/manage.py test my-app
container_name: django
volumes:
- .:/app
ports:
- "8000:8000"
- "8081:8081"
links:
- postgis
- "django-ambassador:selenium"
environment:
- SELENIUM_HOST=http://selenium:4444/wd/hub
selenium:
container_name: selenium
image: selenium/standalone-firefox-debug
ports:
- "4444:4444"
- "5900:5900"
links:
- "django-ambassador:django"
当我检查时 http://DOCKER-MACHINE-IP:4444/wd/hub/static/resource/hub.html 我可以看到 firefox 启动了,但是所有测试都失败了,因为 firefox 无法连接到 django
'Firefox can't establish a connection to the server at localhost:8081'
我在这里也试过这个解决方案https://github.com/docker/compose/issues/1991 但是这不起作用,因为我无法让 django 同时连接到 postgis 和 selenium
'django.db.utils.OperationalError: could not translate host name "postgis" to address: Name or service not known'
我尝试使用下面列出的网络功能
postgis:
dockerfile: ./docker/postgis/Dockerfile
build: .
container_name: postgis
net: appnet
django:
dockerfile: ./docker/Dockerfile-dev
build: .
command: python /app/project/manage.py test foo
container_name: django
volumes:
- .:/app
ports:
- "8000:8000"
- "8081:8081"
net: appnet
environment:
- SELENIUM_HOST=http://selenium:4444/wd/hub
selenium:
container_name: selenium
image: selenium/standalone-firefox-debug
ports:
- "4444:4444"
- "5900:5900"
net: appnet
但结果是一样的
'Firefox can't establish a connection to the server at localhost:8081'
那么我怎样才能让 selenium 连接到 django?
我已经研究了好几天了 - 非常感谢任何帮助。
更多信息
另一个奇怪的事情是,当测试服务器运行宁不使用docker(使用我的virtualenv等旧配置)如果我运行 ./manage.py test foo 我可以通过 http://localhost:8081 的任何浏览器访问服务器并获得网页,但是当我 运行如果我 运行 它在 docker 下,则等效命令。这很奇怪,因为我正在映射端口 8081:8081 - 这是否相关?
注意:我使用的是 OSX 和 Docker v1.9.1
每当您看到本地主机时,首先尝试转发该端口(在 VM 级别)
参见“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"
(将 default
替换为您的 docker 机器的名称:参见 docker-machine ls
)
这与 docker 主机级别的端口映射不同(这是基于 boot2docker 的 Linux 主机)
OP luke-aus confirms
entering the IP address for the network solved the problem!
我最终想出了一个更好的解决方案,不需要我对 IP 地址进行硬编码。下面是我用来 运行 在 django 中使用 docker.
测试的配置Docker-编写文件
# docker-compose base file for everything
version: '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"
Docker文件(对于 Django)
ENTRYPOINT ["/docker/django/entrypoint.sh"]
在入口点文件中
#!/bin/bash
set -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 args
then
# 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_SERVER
fi
eval "$@"
在你的 django 设置文件中
SITE_DOMAIN = 'django'
然后运行你的测试
docker-compose run django ./manage.py test
我也一直在为此苦苦挣扎,我终于找到了适合我的解决方案。你可以尝试这样的事情:
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 address
selenium:
image: selenium/standalone-firefox-debug
ports:
- "5900:5900"
我认为您不需要在 selenium 配置中包含端口 4444。该端口默认公开,无需将其映射到主机,因为 django 容器可以通过其 link 直接访问它到 selenium 容器。
[编辑] 我发现您也不需要显式公开 django 容器的 8081 端口。此外,我为测试服务器使用了一系列端口,因为如果测试是 运行 并行,您可能会遇到 "Address already in use" 错误,如 here.
所述