You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose下Robot Framework容器无法通过localhost访问Web应用

问题:Docker Compose中测试容器无法通过localhost访问前端/后端服务的解决方案

我使用Docker Compose搭建Web应用,并在独立容器中运行Robot Framework做测试。前端与后端服务可通过宿主机的localhost正常连接,但测试容器无法通过https://localhost:3000及https://localhost:8000/api/v1访问应用,仅通过服务名(如isp-frontend:3000)访问可正常工作。请问是否有办法实现测试容器通过localhost访问应用?

相关Docker Compose配置

version: '3.7'

services:
  frontend:
    container_name: isp-frontend
    build:
      context: ./frontend
      dockerfile: Dockerfile.local
    ports:
      - "3000:3000"
    networks:
      - isp-network
    expose:
      - 3000  
    environment:
      # (while it's applied when TS is compiled)
      # For the frontend can be applied only during the build! 
      # You have to build manually without cache if one of those are changed at least for the prod mode.
      - REACT_APP_BACKEND_API=https://localhost:8000/api/v1
      - HTTPS=true
      - SSL_CRT_FILE=/app/dev-cert.dev-pem 
      - SSL_KEY_FILE=/app/dev-key.dev-pem
      - CI=true
      - CHOKIDAR_USEPOLLING=true
    #  - REACT_APP_ENV=sandbox
      
  postgres:
    image: postgres
    environment:
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
      PGDATA: /data/postgres
    volumes:
       - postgres:/data/postgres
    ports:
      - "5432:5432"
    networks:
      - isp-network
    restart: unless-stopped
  
  pgadmin:
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: "test@test.com"
      PGADMIN_DEFAULT_PASSWORD: dev
    volumes:
       - pgadmin:/root/.pgadmin
       - ./pgadmin-config/servers.json:/pgadmin4/servers.json
    ports:
      - "5050:80"
    networks:
      - isp-network
    restart: unless-stopped

  backend:
    container_name: isp-backend
    build:
      context: ./backend
      dockerfile: Dockerfile.local
    # these ports will be accessible internally and published on the host machine.
    ports:
      - "8000:443"
    volumes:
      - ./backend:/app
    command: > 
      bash -c "pip list && env && exec /start-reload.sh"
    networks:
      - isp-network
    depends_on:
      - postgres
    # These ports will be accessible by other services connected to the same network, 
    # but won't be published on the host machine.
    expose:
      - 80
      - 443
    environment:
      - GOOGLE_APPLICATION_CREDENTIALS=/app/.secret/secret.json
      - APP_DB_CONNECTION_STRING=postgresql+psycopg2://test:test@postgres:5432/postgres
      - LOG_LEVEL=debug
      - SQLALCHEMY_ECHO=True
      - CORS=https://localhost:3000,http://localhost:3000,https://isp-frontend:3000
      - PORT=443
      - AUTH_ALLOWED_DOMAINS=*
      - AUTH_REDIRECT_URL=https://localhost:3000/login
      # make uvicorn run as SSL/HTTPS
      - UVICORN_SSL_CERTFILE=/app/dev-cert.dev-pem
      - UVICORN_SSL_KEYFILE=/app/dev-key.dev-pem
      - UVICORN_RELOAD_EXCLUDE=env\*,venv\*,env,venv,.gitlab\*,.pytest_cache\*,.scannerwork\*,.secret\*,.vscode
      - UVICORN_RELOAD_DIR=/app/
      # port of uvicorn inside of the container
      - PRE_START_PATH=/app/scripts/alembic-upgrade.sh

  testing:
    container_name: testing
    build:
      context: ./isp-testing
      dockerfile: Dockerfile
    volumes:
      - ./isp-testing:/isp-app
    command: > 
      bash -c "/wait
      && mkdir -p /isp-app/tests/report
      && cd /isp-app/tests/ 
      && robot --outputdir \"../report/FE_log\" --include US24 ."
    networks:
      - isp-network
    depends_on:
      - backend
      - frontend  
    environment:
      - WAIT_HOSTS=frontend:3000
      - WAIT_TIMEOUT=3000
      - WAIT_SLEEP_INTERVAL=300
      - WAIT_HOST_CONNECT_TIMEOUT=300
      - FRONTEND_URL=https://isp-frontend:3000
      - BACKEND_URL=https://isp-backend:8000/api/v1
      - ROCHE_EMAIL=test@test.com
      - ROCHE_PASS=RJ2ND
      - ROCHE_USERNAME=TEST

volumes:
    postgres:
    pgadmin:
    testing:

networks:
    isp-network:
        driver: bridge

问题原因

Docker容器内的localhost指向容器自身的回环地址,而非宿主机。测试容器里访问localhost:3000时,实际是尝试访问自己容器的3000端口,而非宿主机上映射的前端服务端口,因此无法连通。

解决方案

1. 使用宿主机专用域名host.docker.internal

Docker提供了内置域名host.docker.internal,用于容器访问宿主机。直接修改测试容器的环境变量即可:

testing:
  environment:
    - FRONTEND_URL=https://host.docker.internal:3000
    - BACKEND_URL=https://host.docker.internal:8000/api/v1
  • 注意:Linux系统下Docker版本低于20.10时,需要额外添加extra_hosts配置:
    testing:
      extra_hosts:
        - "host.docker.internal:host-gateway"
    

2. 手动映射localhost到宿主机IP

在测试服务的配置中添加extra_hosts,把localhost指向宿主机的Docker网关IP(通常是172.17.0.1,可通过docker network inspect isp-network查看实际网关):

testing:
  extra_hosts:
    - "localhost:172.17.0.1"

这样测试容器内的localhost就会解析到宿主机,从而访问宿主机上暴露的3000、8000端口。

3. 优先使用服务名访问(推荐)

Docker Compose会自动为同一网络内的服务配置DNS解析,使用服务名(如isp-frontend:3000、isp-backend:443/api/v1)访问是最稳定的方式,无需依赖宿主机IP,也不会因网络配置变化失效。如果不是硬性要求用localhost,建议保持这种方式。

内容的提问来源于stack exchange,提问作者user2439278

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:20:10