Django+Docker+Selenium:live_server_url连接被拒绝问题求助
问题诊断与解决方案
你的问题核心在于Docker容器间的网络访问逻辑错误:Chrome节点容器无法通过localhost访问到Django测试服务器所在的app容器——每个Docker容器的localhost都是自身容器的回环地址,而非宿主机或其他容器的地址,这才导致了ERR_CONNECTION_REFUSED错误。
具体问题点拆解
- 测试服务器绑定与地址生成冲突:你虽然设置了
host = '0.0.0.0',但在setUpClass里又用socket.gethostbyname(socket.gethostname())覆盖了cls.host,可能导致测试服务器没有正确绑定到允许外部容器访问的地址。 - live_server_url地址无效:Chrome容器内部访问
http://localhost:8081只会指向自己容器内部,而你的Django测试服务器运行在app容器里,这个地址自然无法连通。
分步修复方案
1. 修正Django测试类的地址配置
修改BaseTestCase,确保测试服务器绑定到0.0.0.0,同时强制live_server_url使用app容器的服务名(docker-compose中服务名可作为内部DNS域名),让Chrome容器能通过Docker内部网络解析到测试服务器:
@override_settings(ALLOWED_HOSTS=['*']) class BaseTestCase(StaticLiveServerTestCase): # 强制绑定到0.0.0.0,允许所有容器访问测试服务器 host = '0.0.0.0' # 固定测试服务器端口,避免随机端口带来的访问问题 port = 8081 @classmethod def setUpClass(cls): # 不要覆盖host配置,保持为0.0.0.0 super().setUpClass() # 替换live_server_url为app容器的服务名+端口,让Chrome容器能正确访问 cls.live_server_url = f"http://app:{cls.port}" cls.selenium = webdriver.Remote( command_executor='http://hub:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME, ) cls.selenium.implicitly_wait(5) @classmethod def tearDownClass(cls): cls.selenium.quit() super().tearDownClass()
2. 优化docker-compose网络配置
确保所有容器处于同一专属网络(docker-compose默认会创建,但显式声明更清晰),同时确认app容器暴露了测试服务器的端口:
version: '3' networks: selenium-test-net: driver: bridge services: chrome: image: selenium/node-chrome:3.11.0-dysprosium volumes: - /dev/shm:/dev/shm networks: - selenium-test-net environment: HUB_HOST: hub HUB_PORT: '4444' depends_on: - hub hub: image: selenium/hub:3.11.0-dysprosium ports: - "4444:4444" networks: - selenium-test-net app: # 替换为你的app镜像构建/启动配置 build: . ports: - "8081:8081" networks: - selenium-test-net depends_on: - hub # 示例启动命令:运行测试 # command: python manage.py test
3. 关键验证步骤
- 确认app容器的测试服务器确实在
0.0.0.0:8081监听(而非仅绑定localhost)。 - 进入Chrome容器内部,执行
ping app测试DNS解析是否正常(命令:docker exec -it <chrome容器ID> ping app)。 - 测试时检查
live_server_url是否为http://app:8081,而非localhost:8081。
额外提示
如果不想固定测试端口,可以通过cls.server_thread.port获取随机分配的端口,再拼接为http://app:{cls.server_thread.port}。
内容的提问来源于stack exchange,提问作者AntoineLB
相关产品推荐
相关产品推荐

