Docker化Django应用与Cucumber测试的端口冲突及容器通信问题求解
问题修复方案
核心问题根因
端口冲突是因为test和app两个服务都配置了绑定宿主机8000端口的映射规则,同时Cucumber测试容器不需要对外暴露端口,且跨容器调用需要用Docker内置的域名解析规则。
具体修改步骤
1. 修改docker-compose.yaml配置
version: "3.8" services: test: build: ./cucumber_drf_tests image: cucumber_test container_name: cucumber_container # 删掉原来的ports配置,测试客户端不需要暴露端口 depends_on: - app # 可选配置:测试跑完不自动重启 restart: "no" app: build: . image: app:django container_name: django_rest_container ports: - 8000:8000 # 仅保留Django的端口映射,方便宿主机访问 volumes: # 修正挂载路径和Dockerfile的WORKDIR一致,避免代码不同步 - .:/app/src command: > bash -c "python manage.py migrate && python manage.py loaddata ./project_apps/fixtures/dummy_data.json && python manage.py runserver 0.0.0.0:8000" depends_on: - db db: image: postgres container_name: postgres_db volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=postgres - POSTGRES_USER=bla - POSTGRES_PASSWORD=blaa
2. 修改Cucumber API调用地址
Docker Compose会自动为同一集群下的服务做域名解析,服务名就是访问域名。找到cucumber_drf_tests目录下的接口配置文件(config.js或axiosinst.js),把原来的API基地址从http://localhost:8000修改为http://app:8000即可。
3. 优化Cucumber的Dockerfile
FROM node:12 WORKDIR /app/src COPY package*.json ./ RUN npm install COPY . . # 删掉不需要的EXPOSE配置,测试服务不需要监听端口 # 统一包管理工具,用npm执行命令避免yarn未安装的问题 CMD ["npm", "run", "cucumber-drf"]
运行验证
- 执行
docker compose up会自动启动数据库、Django服务,待Django启动完成后自动执行Cucumber测试 - 如果需要手动触发测试,执行
docker compose run test即可,测试完成后容器自动退出
相关最佳实践
- 仅需要宿主机访问的服务才配置端口映射,内部调用的服务不需要映射端口
- 同一Docker Compose集群内的服务互调用直接使用服务名作为域名,不要使用localhost或宿主机IP
- 容器的工作路径要保持统一:Dockerfile的
WORKDIR、挂载路径、启动命令中的路径需要一致,避免出现找不到文件的异常 - 测试类服务建议配置
restart: "no",避免测试执行完成后异常重启 - 可以在测试启动前增加等待逻辑,确保Django服务完全启动后再执行测试,避免接口调用失败:可以在test服务的command中增加轮询判断,比如
bash -c "until curl -s http://app:8000/health; do sleep 1; done; npm run cucumber-drf"
内容的提问来源于stack exchange,提问作者htodev
相关产品推荐
相关产品推荐

