gpt4 book ai didi

C# + DockerCompose - 在尝试连接之前等待 MS SQL Server Docker 容器启动

转载 作者:行者123 更新时间:2023-12-05 05:16:06 34 4
gpt4 key购买 nike

我正在尝试为我的微服务创建类似于 Spotify's approach 的集成测试.

我仍在研究如何启动和播种数据库。目前我有一个 .NET Core 2.0 项目 FluentDocker v2.2.15 和 DbUp 4.1.0.

我使用 FluentDocker 调用 DockerCompose 并启动我的服务,包括 SQL Server container

var hosts = new Hosts().Discover();
var dockerHost = hosts.FirstOrDefault(x => x.IsNative) ?? hosts.FirstOrDefault(x => x.Name == "default");

if (dockerHost == null)
{
return;
}

var composeFile = Args["composeFile"];

var result = dockerHost.Host.ComposeUp(composeFile: composeFile);

然后我使用 DbUp 运行我的脚本并为数据库播种。

var connectionString = Args["connectionString"];
var scriptsPath = Args["scriptsPath"];

EnsureDatabase.For.SqlDatabase(connectionString);

var upgradeEngine = DeployChanges.To.SqlDatabase(connectionString).WithScriptsFromFileSystem(scriptsPath).Build();

var result = upgradeEngine.PerformUpgrade();

当我给 SQL Server 足够的时间启动时,例如,在调试时,我可以成功运行它。但是,如果我全速运行它,则 DbUp 会在 SQL Server 尚未准备就绪时尝试连接到它。FluentDocker 有一个 WaitForPort方法,但它似乎不适用于 DockerCompose API。

我想知道是否有办法在运行脚本之前等待 SQL Server 的端口 1433 响应(不包括非确定性策略,例如 await Task.Delay),或者是否有是允许我拥有这种控制权的替代库。

谢谢

最佳答案

您可以在 FluentDocker v2.6.2。例如:

给定 docker-compose 文件:

version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress

wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:

该文件指定wordpress依赖于db,因此先启动db,然后实例化wordpress容器。但要确保在using 子句表明 wordpress 网络正在运行,您需要使用 HTTP 来确定这一点。您可以使用 Fluent API 像这样实例化并等待服务启动。

  var file = Path.Combine(Directory.GetCurrentDirectory(),
(TemplateString) "Resources/ComposeTests/WordPress/docker-compose.yml");

using (new Builder()
.UseContainer()
.UseCompose()
.FromFile(file)
.RemoveOrphans()
.Wait("wordpress", (service, cnt) => {
if (cnt > 60) throw new FluentDockerException("Failed to wait for wordpress service");

var res = HttpExtensions.DoRequest("http://localhost:8000/wp-admin/install.php").Result;
return (res.Code == HttpStatusCode.OK &&
res.Body.IndexOf("https://wordpress.org/", StringComparison.Ordinal) != -1) ? 0 : 500;
})
.Build().Start())
{
// Since we have waited - this shall now always work.
var installPage = await "http://localhost:8000/wp-admin/install.php".Wget();
Assert.IsTrue(installPage.IndexOf("https://wordpress.org/", StringComparison.Ordinal) != -1);
}

(上面的示例是一个更麻烦的 WaitForHttp 但使用自定义 lambda 来说明这一点)。

通过这种方式,您甚至可以使用db 连接 并在继续之前查询表。大于零的返回值是等待下一次测试的时间。零及以下将成功结束等待。异常将终止等待(并失败)。

上面的示例使用了 FluentAPI 语法,但您可以手动添加一个钩子(Hook)到 compose 容器上并自行使用扩展。

干杯, 马里奥

关于C# + DockerCompose - 在尝试连接之前等待 MS SQL Server Docker 容器启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50877625/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com