我有一个使用MySQL Test容器的小型集成测试。
当我在本地构建时,运行简单的gradlew build命令,它将运行,测试并构建项目。但是,当我尝试使用正式的gradle docker映像时,该测试将暂停,以等待mysql数据库的可用性。
运行我的构建时,它将创建3个容器:
我的gradle映像不同于官方映像,因为它安装了docker:
FROM gradle
USER root
RUN apt-get update && \
apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && \
apt-key fingerprint 0EBFCD88 && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable" && \
apt-get update && \
apt-get install -y docker-ce docker-ce-cli containerd.io
当连接停止时,我连接到了gradle映像,并安装了mysql客户端。我尝试连接到测试正在连接的同一映像,并且连接没有问题。 没有人知道我在做什么错,因为仅在容器中运行构建会出现此问题?
我用这个来跑
docker container run -v /var/run/docker.sock:/var/run/docker.sock -v <local repo>:/home/gradle/project -w /home/gradle/project --rm mygradle gradle build -i
编辑: 这不是因为gradle docker映像,而是任何映像。如果我使用Jenkins运行,并且它是一个容器,那么这也行不通。尝试连接到172.x.x.1(主机地址)和暴露的端口,并且测试未连接,但是访问容器,并使用mysql客户端尝试相同的完全连接,就可以连接。
答案 0 :(得分:0)
我找到了解决方案。
我没有使用MysqlContainer类,而是定义了一个扩展该类的新类。它将检测应用程序是否在容器内运行,如果是,它将尝试在内部连接到数据库容器,而不是使用localhost和生成的端口。
public static class IntegrationTestsDatabase<SELF extends MySQLContainer<SELF>> extends MySQLContainer<SELF> {
public IntegrationTestsDatabase() {
}
public IntegrationTestsDatabase(String dockerImageName) {
super(dockerImageName);
}
public String getJdbcUrl() {
String containerIp = ((ContainerNetwork)this.getContainerInfo().getNetworkSettings().getNetworks().values().stream().findFirst().get()).getIpAddress();
return this.isRunningInsideDocker() ? "jdbc:mysql://" + containerIp + ":" + MySQLContainer.MYSQL_PORT + "/" + this.getDatabaseName() : super.getJdbcUrl();
}
public Boolean isRunningInsideDocker() {
try {
Stream stream = Files.lines(Paths.get("/proc/1/cgroup"));
Boolean var2;
try {
var2 = stream.anyMatch((line) -> {
return line.contains("/docker");
});
} catch (Throwable var5) {
if (stream != null) {
try {
stream.close();
} catch (Throwable var4) {
var5.addSuppressed(var4);
}
}
throw var5;
}
if (stream != null) {
stream.close();
}
return var2;
} catch (IOException var6) {
return false;
}
}
}
这将与其他容器类型一起使用。