测试容器:忽略来自 Dockerfile 的父“EXPOSE”指令
Test containers: ignore parent `EXPOSE` instruction from Dockerfile
我正在尝试 运行 Couchbase v.5.1.1 docker 容器用于测试目的,通过具有固定暴露端口的测试容器,例如:
trait CouchbaseTestEnvironment extends ForAllTestContainer {
this: Suite =>
def couchbaseContainer: FixedHostPortGenericContainer = {
val consumer = new Slf4jLogConsumer(LoggerFactory.getLogger(getClass))
/*
* Couchbase should know which ports are exposed for client, because this is how it exposes services.
* E.g. client ask only for on port - say 8091. And query service port is 8093. So client, won't ask for every port,
* instead CB will tell client on which port query service exposed, that's why CB should be aware about port mapping.
* That's why we need to give CB port mappings
*
* See for more details:
*
*/
def randomPort: Int = {
val (from, to) = (32768, 35000) //linux private port range
from + Random.nextInt(to - from)
}
val random8091Port = randomPort
val random8092Port = randomPort
val random8093Port = randomPort
val random8094Port = randomPort
val random11210Port = randomPort
val container = FixedHostPortGenericContainer(
imageName = "couchbase:community-5.0.1",
exposedHostPort = random8091Port,
exposedContainerPort = random8091Port,
env = Map(
"COUCHBASE_RANDOM_PORT_8091" -> random8091Port.toString,
"COUCHBASE_RANDOM_PORT_8092" -> random8092Port.toString,
"COUCHBASE_RANDOM_PORT_8093" -> random8093Port.toString,
"COUCHBASE_RANDOM_PORT_8094" -> random8094Port.toString,
"COUCHBASE_RANDOM_PORT_11210" -> random11210Port.toString
)
)
container.container.withFixedExposedPort(random8092Port, random8092Port)
container.container.withFixedExposedPort(random8093Port, random8093Port)
container.container.withFixedExposedPort(random8094Port, random8094Port)
container.container.withFixedExposedPort(random11210Port, random11210Port)
container.container.withLogConsumer(consumer)
container
}
}
如您所见,应公开 5 个固定端口。
但是,当我进行 运行ning 测试时,我实际上可以看到,而是其他端口公开了随机端口:
docker ps
f4fc1ce06544 couchbase:community-5.0.1 "/entrypoint.sh /opt…" 59 seconds ago Up 1 second 0.0.0.0:55264->8091/tcp, 0.0.0.0:55263->8092/tcp, 0.0.0.0:55262->8093/tcp, 0.0.0.0:55261->8094/tcp, 0.0.0.0:55260->11207/tcp, 0.0.0.0:55259->11210/tcp, 0.0.0.0:55258->11211/tcp, 0.0.0.0:55257->18091/tcp, 0.0.0.0:55256->18092/tcp, 0.0.0.0:55255->18093/tcp, 0.0.0.0:55254->18094/tcp unruffled_mendel
03b491ac2ea8 testcontainersofficial/ryuk:0.3.0
所以你可以看到另一个端口被暴露,并映射到随机端口而不是固定的。
据我了解,测试容器会忽略我提供的端口,而是公开来自 Couchbase Dockerfile 的端口:https://github.com/couchbase/docker/blob/master/community/couchbase-server/5.1.1/Dockerfile#L74
EXPOSE 8091 8092 8093 8094 8095 8096 11207 11210 11211 18091 18092 18093 18094 18095 18096
我能否以某种方式强制测试容器忽略 EXPOSE
指令?
部分帮助问题:Couchbase in docker for integration tests: Make the ports 8092, 8093, 8094 and 8095 configurable to be able to use docker’s random ports
Can I somehow force Test containers to ignore EXPOSE instruction?
我不知道是否有针对此的简单配置选项,但我找到的一个解决方法是使用 the docker-java create container command customization 的高级功能。我在 Java 中提供了一个示例,请自行将其翻译成 Scala。在从函数返回容器对象之前将其作为最后一个命令应用:
container.withCreateContainerCmdModifier(
cmd -> cmd.getHostConfig().withPublishAllPorts(false)
);
这里的重点是.withPublishAllPorts(false)
的用法。根据我的理解,这与 docker run
命令的 --publish-all
(或 -P
)参数相同。 Testcontainers 库 sets 这个值默认为 true
。此修改将其覆盖为 false
.
使用此配置,您的示例根本不会发布任何端口,而不是按预期修复的 5 个端口:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ee4fb91b97c couchbase:community-5.0.1 "/entrypoint.sh couc…" 33 seconds ago Up 32 seconds 8091-8094/tcp, 11207/tcp, 11210-11211/tcp, 18091-18094/tcp trusting_keldysh
这是因为在您提供的答案中,作者创建了一个特殊的自定义 docker couchbase 图像,它“理解”环境变量,如 COUCHBASE_RANDOM_PORT_8091
。您的代码使用标准的 couchbase 图像 couchbase:community-5.0.1
,它基本上只是忽略了这些环境变量。因此,为了 运行 在非标准内部端口上使用 couchbase,您需要使用“魔术”configure-node.sh
脚本构建自定义映像,该脚本使用环境变量中提供的值调整 couchbase 配置。
希望对你有所帮助:)
我正在尝试 运行 Couchbase v.5.1.1 docker 容器用于测试目的,通过具有固定暴露端口的测试容器,例如:
trait CouchbaseTestEnvironment extends ForAllTestContainer {
this: Suite =>
def couchbaseContainer: FixedHostPortGenericContainer = {
val consumer = new Slf4jLogConsumer(LoggerFactory.getLogger(getClass))
/*
* Couchbase should know which ports are exposed for client, because this is how it exposes services.
* E.g. client ask only for on port - say 8091. And query service port is 8093. So client, won't ask for every port,
* instead CB will tell client on which port query service exposed, that's why CB should be aware about port mapping.
* That's why we need to give CB port mappings
*
* See for more details:
*
*/
def randomPort: Int = {
val (from, to) = (32768, 35000) //linux private port range
from + Random.nextInt(to - from)
}
val random8091Port = randomPort
val random8092Port = randomPort
val random8093Port = randomPort
val random8094Port = randomPort
val random11210Port = randomPort
val container = FixedHostPortGenericContainer(
imageName = "couchbase:community-5.0.1",
exposedHostPort = random8091Port,
exposedContainerPort = random8091Port,
env = Map(
"COUCHBASE_RANDOM_PORT_8091" -> random8091Port.toString,
"COUCHBASE_RANDOM_PORT_8092" -> random8092Port.toString,
"COUCHBASE_RANDOM_PORT_8093" -> random8093Port.toString,
"COUCHBASE_RANDOM_PORT_8094" -> random8094Port.toString,
"COUCHBASE_RANDOM_PORT_11210" -> random11210Port.toString
)
)
container.container.withFixedExposedPort(random8092Port, random8092Port)
container.container.withFixedExposedPort(random8093Port, random8093Port)
container.container.withFixedExposedPort(random8094Port, random8094Port)
container.container.withFixedExposedPort(random11210Port, random11210Port)
container.container.withLogConsumer(consumer)
container
}
}
如您所见,应公开 5 个固定端口。 但是,当我进行 运行ning 测试时,我实际上可以看到,而是其他端口公开了随机端口:
docker ps
f4fc1ce06544 couchbase:community-5.0.1 "/entrypoint.sh /opt…" 59 seconds ago Up 1 second 0.0.0.0:55264->8091/tcp, 0.0.0.0:55263->8092/tcp, 0.0.0.0:55262->8093/tcp, 0.0.0.0:55261->8094/tcp, 0.0.0.0:55260->11207/tcp, 0.0.0.0:55259->11210/tcp, 0.0.0.0:55258->11211/tcp, 0.0.0.0:55257->18091/tcp, 0.0.0.0:55256->18092/tcp, 0.0.0.0:55255->18093/tcp, 0.0.0.0:55254->18094/tcp unruffled_mendel
03b491ac2ea8 testcontainersofficial/ryuk:0.3.0
所以你可以看到另一个端口被暴露,并映射到随机端口而不是固定的。
据我了解,测试容器会忽略我提供的端口,而是公开来自 Couchbase Dockerfile 的端口:https://github.com/couchbase/docker/blob/master/community/couchbase-server/5.1.1/Dockerfile#L74
EXPOSE 8091 8092 8093 8094 8095 8096 11207 11210 11211 18091 18092 18093 18094 18095 18096
我能否以某种方式强制测试容器忽略 EXPOSE
指令?
部分帮助问题:Couchbase in docker for integration tests: Make the ports 8092, 8093, 8094 and 8095 configurable to be able to use docker’s random ports
Can I somehow force Test containers to ignore EXPOSE instruction?
我不知道是否有针对此的简单配置选项,但我找到的一个解决方法是使用 the docker-java create container command customization 的高级功能。我在 Java 中提供了一个示例,请自行将其翻译成 Scala。在从函数返回容器对象之前将其作为最后一个命令应用:
container.withCreateContainerCmdModifier(
cmd -> cmd.getHostConfig().withPublishAllPorts(false)
);
这里的重点是.withPublishAllPorts(false)
的用法。根据我的理解,这与 docker run
命令的 --publish-all
(或 -P
)参数相同。 Testcontainers 库 sets 这个值默认为 true
。此修改将其覆盖为 false
.
使用此配置,您的示例根本不会发布任何端口,而不是按预期修复的 5 个端口:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ee4fb91b97c couchbase:community-5.0.1 "/entrypoint.sh couc…" 33 seconds ago Up 32 seconds 8091-8094/tcp, 11207/tcp, 11210-11211/tcp, 18091-18094/tcp trusting_keldysh
这是因为在您提供的答案中,作者创建了一个特殊的自定义 docker couchbase 图像,它“理解”环境变量,如 COUCHBASE_RANDOM_PORT_8091
。您的代码使用标准的 couchbase 图像 couchbase:community-5.0.1
,它基本上只是忽略了这些环境变量。因此,为了 运行 在非标准内部端口上使用 couchbase,您需要使用“魔术”configure-node.sh
脚本构建自定义映像,该脚本使用环境变量中提供的值调整 couchbase 配置。
希望对你有所帮助:)