首页 > 解决方案 > 运行时访问docker容器的IP

问题描述

我有用 selenium 编写的跨浏览器测试。由于我想在多个平台上测试多个浏览器,我使用 docker 虚拟化和 selenium 网格。我可以在没有 docker 的情况下通过 localhost:4444 执行我的测试docker-compose.yml

version: "3"
services:
  hub:
    image: selenium/hub
    ports:
      - "4444:4444"
    environment:
      GRID_MAX_SESSION: 16
      GRID_BROWSER_TIMEOUT: 3000
      GRID_TIMEOUT: 3000

  chrome:
    image: selenium/node-chrome
    container_name: web-automation_chrome
    depends_on:
      - hub
    environment:
      HUB_PORT_4444_TCP_ADDR: hub
      HUB_PORT_4444_TCP_PORT: 4444
      NODE_MAX_SESSION: 4
      NODE_MAX_INSTANCES: 4
    volumes:
      - /dev/shm:/dev/shm
    ports:
      - "9001:5900"

  firefox:
    image: selenium/node-firefox
    container_name: web-automation_firefox
    depends_on:
      - hub
    environment:
      HUB_PORT_4444_TCP_ADDR: hub
      HUB_PORT_4444_TCP_PORT: 4444
      NODE_MAX_SESSION: 2
      NODE_MAX_INSTANCES: 2
    volumes:
      - /dev/shm:/dev/shm
    ports:
      - "9002:5900"

  opera:
    image: selenium/node-opera
    container_name: web-automation_opera
    depends_on:
      - hub
    environment:
      HUB_PORT_4444_TCP_ADDR: hub
      HUB_PORT_4444_TCP_PORT: 4444
      NODE_MAX_SESSION: 2
      NODE_MAX_INSTANCES: 2
    volumes:
      - /dev/shm:/dev/shm
    ports:
      - "9003:5900"

我刚刚用 maven 执行了我的测试,他们会成功。然后我计划将我的浏览器 JUnit 测试也容器化并创建了这个 Dockerfile:

FROM openjdk:11 as build
WORKDIR /workspace/app

COPY .git .git
COPY mvnw .
COPY .mvn .mvn
COPY wait-for-it.sh .
RUN ["chmod", "+x", "wait-for-it.sh"]
COPY pom.xml .
COPY src src

RUN ./wait-for-it.sh hub:4444 -- ./mvnw clean package

FROM openjdk:11
VOLUME /tmp
COPY --from=build /workspace/app/target/*.jar app.jar

哪个也可以正常工作,并将这部分添加到我的docker-compose.yml

  app:
    build: .
    ports:
      - "80:8080"
    depends_on:
      - "hub"

我一运行docker-compose up,maven 就成功构建了测试,并且成功设置了 selenium 网格,但我收到以下错误:

[ERROR] loginUserNotExistentFirefox  Time elapsed: 0.033 s  <<< ERROR!
org.openqa.selenium.remote.UnreachableBrowserException: 
Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: '7e67c412b3c0', ip: '172.17.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.19.121-linuxkit', java.version: '11.0.9.1'
Driver info: driver.version: RemoteWebDriver
        at org.seleniumtests.frontendtests.tests.TestLogin.loginUserNotExistentFirefox(TestLogin.java:29)
Caused by: java.net.UnknownHostException: hub
        at org.seleniumtests.frontendtests.tests.TestLogin.loginUserNotExistentFirefox(TestLogin.java:29)

这就是我计划从我的app容器中访问服务的方式。

    driver = new RemoteWebDriver(new URL("http://hub:4444/wd/hub"),
                                                             DesiredCapabilities.operaBlink());

标签: dockerdocker-composeselenium-griddocker-networking

解决方案


第一个问题:您无法连接到 localhost:4444

您的服务之间有一个桥梁(默认情况下在 Docker Compose 中),您可以通过 访问另一个服务<service_name>:<service_port>,因此您可以通过 访问中心服务hub:4444

第二个问题,可能是你解决第一个问题的结果

从官方 Docker Compose 文档中,您可以在此处阅读:

您可以使用 depends_on 选项控制服务启动和关闭的顺序。Compose 总是按依赖顺序启动和停止容器,其中依赖由depends_on、links、volumes_from 和network_mode 确定:“service:...”。

正如你对depends_on所做的那样,但是

但是,对于启动,Compose 不会等到容器“准备好”(无论这对您的特定应用程序意味着什么)——只等到它运行。这是有充分理由的。

Docker Compose 官方解决方案

使用诸如wait-for-itdockerize、 sh-compatible wait-forRelayAndContainers模板之类的工具。这些是小型包装脚本,您可以将它们包含在应用程序的映像中,以轮询给定的主机和端口,直到它接受 TCP 连接。

他们建议你这样做:

version: "3"
services:
  hub:
    image: selenium/hub
    ports:
      - "4444:4444"
    environment:
      GRID_MAX_SESSION: 16
      GRID_BROWSER_TIMEOUT: 3000
      GRID_TIMEOUT: 3000

  app:
    build: .
    ports:
      - "80:8080"
    depends_on:
      - "hub"
    command: ["./wait-for-it.sh", "hub:4444", "--", "java", "-jar", "app.jar"]

推荐阅读