运行时访问 docker 个容器的 IP

Access IP of docker container at runtime

我有用 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());

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

你的服务之间有一个桥(默认在Docker Compose),你可以通过<service_name>:<service_port>访问另一个服务,所以你可以访问hub 服务由 hub:4444.

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

来自官方 Docker Compose 文档,您可以阅读 here:

You can control the order of service startup and shutdown with the depends_on option. Compose always starts and stops containers in dependency order, where dependencies are determined by depends_on, links, volumes_from, and network_mode: "service:...".

与您对 depends_on 所做的一样,但是

However, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) - only until it’s running. There’s a good reason for this.

Docker 编写官方解决方案

Use a tool such as wait-for-it, dockerize, sh-compatible wait-for, or RelayAndContainers template. These are small wrapper scripts which you can include in your application’s image to poll a given host and port until it’s accepting TCP connections.

他们建议你这样做:

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"]