是否可以使用 Docker.DotNet 在 Azure Pipelines 上以编程方式启动容器?
Is it possible to use Docker.DotNet to start a container programmatically on Azure Pipelines?
我有一个微服务应用程序,我不想启动整个堆栈以进行 运行 集成测试。这个想法是能够 运行 来自 Test Explorer 的测试 Visual Studio。所以我不想创建一个 shell 脚本来完成这个。
思路是在容器中启动所有外部微服务依赖,然后运行被测系统的一个TestServer接收测试请求,以便系统调用其他微服务。
我找到了 this 库并喜欢以编程方式启动容器以实现上述目的的想法。
我不知道这是否可以在 Azure Pipeline 上运行 运行。 Azure 上用于初始化 Docker.DotNet 的正确 docker 引擎地址是什么?
// Default Docker Engine on Windows
using Docker.DotNet;
DockerClient client = new DockerClientConfiguration(
new Uri("npipe://./pipe/docker_engine"))
.CreateClient();
// Default Docker Engine on Linux
using Docker.DotNet;
DockerClient client = new DockerClientConfiguration(
new Uri("unix:///var/run/docker.sock"))
.CreateClient();
What I don't know, is if this would work running on an Azure Pipeline.
What would be the correct docker engine address on Azure to initialize
Docker.DotNet?
您可以在托管 windows 代理中运行的管道中添加 Powershell task,内容如下:
[System.IO.Directory]::GetFiles("\.\pipe\") | Select-String "docker"
如果我使用托管 windows2019 代理,结果如下:
所以我认为地址是 \.\pipe\docker_engine
(不确定在您的代码中使用时是否需要一些更改,例如斜杠和反斜杠)。
我做了一些研究,发现 Ms 托管代理的 Windows 和 Linux 图像都预装了 Docker 和 Docker-Compose,所以可以使用这些代理启动容器。
我的问题是我没有意识到 Ops 团队配置了 Linux 代理。我试图使用 Windows 命名管道而不是 Unix 套接字来执行。
我相应地更改了 Docker 引擎 API 地址并且它起作用了。
这是我的代码,以防有人有兴趣创建集成测试来启动微服务依赖项的容器:
using Docker.DotNet;
using System;
using System.Runtime.InteropServices;
namespace Relationship.Promotion.Applier.IntegrationTest.Helpers
{
public class DockerClientFactory
{
private static readonly Uri defaultWindowsDockerEngineUri = new Uri("npipe://./pipe/docker_engine");
private static readonly Uri defaultLinuxDockerEngineUri = new Uri("unix:///var/run/docker.sock");
public static DockerClient CreateInstance()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return new DockerClientConfiguration(defaultWindowsDockerEngineUri).CreateClient();
else
return new DockerClientConfiguration(defaultLinuxDockerEngineUri).CreateClient();
}
}
}
namespace Relationship.Promotion.Applier.IntegrationTest
{
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
private readonly DockerClient dockerClient;
private readonly PromotionContainer promotionContainer;
private readonly StoreContainer storeContainer;
private readonly ConversionContainer conversionContainer;
public CustomWebApplicationFactory()
{
try
{
// Alternative to Docker.DotNet
// https://github.com/Deffiss/testenvironment-docker
dockerClient = DockerClientFactory.CreateInstance();
DockerContainerBase.CleanupOrphanedContainers(dockerClient).Wait(300.Seconds());
if (!dockerClient.Networks.ListNetworksAsync().Result.Select(n => n.Name).Contains("boti-network"))
{
var result = dockerClient.Networks.CreateNetworkAsync(new Docker.DotNet.Models.NetworksCreateParameters()
{
Name = "boti-network",
Driver = "bridge"
}).Result;
}
promotionContainer = new PromotionContainer(imageName: "promotion-engine-promotion-api");
promotionContainer.Start(dockerClient).Wait(300.Seconds());
conversionContainer = new ConversionContainer(imageName: "promotion-engine-conversion-api");
conversionContainer.Start(dockerClient).Wait(300.Seconds());
storeContainer = new StoreContainer("promotion-engine-store-api");
storeContainer.Start(dockerClient).Wait(300.Seconds());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
protected override IWebHostBuilder CreateWebHostBuilder()
{
return base.CreateWebHostBuilder().UseEnvironment("Docker");
}
protected override void Dispose(bool itIsSafeToAlsoFreeManagedObjects)
{
if (!itIsSafeToAlsoFreeManagedObjects) return;
promotionContainer.Remove(dockerClient).Wait(300.Seconds());
conversionContainer.Remove(dockerClient).Wait(300.Seconds());
storeContainer.Remove(dockerClient).Wait(300.Seconds());
dockerClient.Dispose();
base.Dispose(itIsSafeToAlsoFreeManagedObjects);
}
}
}
我有一个微服务应用程序,我不想启动整个堆栈以进行 运行 集成测试。这个想法是能够 运行 来自 Test Explorer 的测试 Visual Studio。所以我不想创建一个 shell 脚本来完成这个。
思路是在容器中启动所有外部微服务依赖,然后运行被测系统的一个TestServer接收测试请求,以便系统调用其他微服务。
我找到了 this 库并喜欢以编程方式启动容器以实现上述目的的想法。
我不知道这是否可以在 Azure Pipeline 上运行 运行。 Azure 上用于初始化 Docker.DotNet 的正确 docker 引擎地址是什么?
// Default Docker Engine on Windows
using Docker.DotNet;
DockerClient client = new DockerClientConfiguration(
new Uri("npipe://./pipe/docker_engine"))
.CreateClient();
// Default Docker Engine on Linux
using Docker.DotNet;
DockerClient client = new DockerClientConfiguration(
new Uri("unix:///var/run/docker.sock"))
.CreateClient();
What I don't know, is if this would work running on an Azure Pipeline. What would be the correct docker engine address on Azure to initialize Docker.DotNet?
您可以在托管 windows 代理中运行的管道中添加 Powershell task,内容如下:
[System.IO.Directory]::GetFiles("\.\pipe\") | Select-String "docker"
如果我使用托管 windows2019 代理,结果如下:
所以我认为地址是 \.\pipe\docker_engine
(不确定在您的代码中使用时是否需要一些更改,例如斜杠和反斜杠)。
我做了一些研究,发现 Ms 托管代理的 Windows 和 Linux 图像都预装了 Docker 和 Docker-Compose,所以可以使用这些代理启动容器。
我的问题是我没有意识到 Ops 团队配置了 Linux 代理。我试图使用 Windows 命名管道而不是 Unix 套接字来执行。
我相应地更改了 Docker 引擎 API 地址并且它起作用了。
这是我的代码,以防有人有兴趣创建集成测试来启动微服务依赖项的容器:
using Docker.DotNet;
using System;
using System.Runtime.InteropServices;
namespace Relationship.Promotion.Applier.IntegrationTest.Helpers
{
public class DockerClientFactory
{
private static readonly Uri defaultWindowsDockerEngineUri = new Uri("npipe://./pipe/docker_engine");
private static readonly Uri defaultLinuxDockerEngineUri = new Uri("unix:///var/run/docker.sock");
public static DockerClient CreateInstance()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return new DockerClientConfiguration(defaultWindowsDockerEngineUri).CreateClient();
else
return new DockerClientConfiguration(defaultLinuxDockerEngineUri).CreateClient();
}
}
}
namespace Relationship.Promotion.Applier.IntegrationTest
{
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
private readonly DockerClient dockerClient;
private readonly PromotionContainer promotionContainer;
private readonly StoreContainer storeContainer;
private readonly ConversionContainer conversionContainer;
public CustomWebApplicationFactory()
{
try
{
// Alternative to Docker.DotNet
// https://github.com/Deffiss/testenvironment-docker
dockerClient = DockerClientFactory.CreateInstance();
DockerContainerBase.CleanupOrphanedContainers(dockerClient).Wait(300.Seconds());
if (!dockerClient.Networks.ListNetworksAsync().Result.Select(n => n.Name).Contains("boti-network"))
{
var result = dockerClient.Networks.CreateNetworkAsync(new Docker.DotNet.Models.NetworksCreateParameters()
{
Name = "boti-network",
Driver = "bridge"
}).Result;
}
promotionContainer = new PromotionContainer(imageName: "promotion-engine-promotion-api");
promotionContainer.Start(dockerClient).Wait(300.Seconds());
conversionContainer = new ConversionContainer(imageName: "promotion-engine-conversion-api");
conversionContainer.Start(dockerClient).Wait(300.Seconds());
storeContainer = new StoreContainer("promotion-engine-store-api");
storeContainer.Start(dockerClient).Wait(300.Seconds());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
protected override IWebHostBuilder CreateWebHostBuilder()
{
return base.CreateWebHostBuilder().UseEnvironment("Docker");
}
protected override void Dispose(bool itIsSafeToAlsoFreeManagedObjects)
{
if (!itIsSafeToAlsoFreeManagedObjects) return;
promotionContainer.Remove(dockerClient).Wait(300.Seconds());
conversionContainer.Remove(dockerClient).Wait(300.Seconds());
storeContainer.Remove(dockerClient).Wait(300.Seconds());
dockerClient.Dispose();
base.Dispose(itIsSafeToAlsoFreeManagedObjects);
}
}
}