在运行时访问docker容器的IP



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

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就成功构建了测试,硒网格也成功设置,但我收到了以下错误:

[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:4444访问hub服务。

第二个问题,当你解决第一个问题时,它可能是结果

从官方Docker Compose文档,您可以在这里阅读:

您可以使用dependens_on选项控制服务启动和关闭的顺序。Compose总是按依赖关系顺序启动和停止容器,其中依赖关系由dependents_on、links、volumes_from和network_mode决定:";服务:&";。

正如您对dependens_on所做的那样,但

但是,对于启动来说,Compose不会等到容器"准备就绪"(无论这对您的特定应用程序意味着什么(,只会等到它正在运行。这是有充分理由的。

Docker Compose官方解决方案

使用诸如wait for it、dockerize、sh compatible wait for或RelayAndContainers模板。这些是小包装脚本可以包含在应用程序的映像中,以轮询给定的主机和端口直到它接受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"]