是否可以使用Docker.DotNet在Azure管道上以编程方式启动容器?

是否可以使用Docker.DotNet在Azure管道上以编程方式启动容器?,docker,asp.net-core,docker-compose,microservices,azure-pipelines,Docker,Asp.net Core,Docker Compose,Microservices,Azure Pipelines,我有一个microservices应用程序,我不想启动整个堆栈来运行集成测试。其想法是能够从VisualStudio中的测试资源管理器运行测试。所以我不想创建一个shell脚本来完成这个任务 其思想是在容器中启动所有外部微服务依赖项,然后运行被测系统的TestServer来接收测试请求,以便系统可以调用其他微服务 我找到了这个库,并喜欢通过编程启动容器来实现上述功能 我不知道的是,这是否可以在Azure管道上运行。Azure上初始化docker.DotNet的正确docker引擎地址是什么 //

我有一个microservices应用程序,我不想启动整个堆栈来运行集成测试。其想法是能够从VisualStudio中的测试资源管理器运行测试。所以我不想创建一个shell脚本来完成这个任务

其思想是在容器中启动所有外部微服务依赖项,然后运行被测系统的TestServer来接收测试请求,以便系统可以调用其他微服务

我找到了这个库,并喜欢通过编程启动容器来实现上述功能

我不知道的是,这是否可以在Azure管道上运行。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();
我不知道的是,这是否可以在Azure管道上运行。 Azure上要初始化的正确docker引擎地址是什么 Docker.DotNet

// 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();
您可以在托管windows agent中运行的管道中添加以下内容:

[System.IO.Directory]::GetFiles("\\.\\pipe\\") | Select-String "docker"
以下是使用托管windows2019代理的结果:


因此,我认为地址是
\.\\pipe\\docker\u engine
(不确定在代码中使用时是否需要一些更改,如斜杠和反斜杠)。

我做了一些研究,发现Ms托管代理的Windows和Linux映像都预装了docker和docker Compose,因此,可以使用这些代理启动容器

我的问题是,我没有意识到Ops团队配置了Linux代理。我试图使用一个名为pipe的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);
        }
    }
}
使用Docker.DotNet;
使用制度;
使用System.Runtime.InteropServices;
命名空间关系.Promotion.Applier.IntegrationTest.Helpers
{
公营码头工厂
{
私有静态只读Uri defaultWindowsDockerEngineUri=新Uri(“npipe://./pipe/docker_engine");
私有静态只读Uri defaultLinuxDockerEngineUri=新Uri(“unix:///var/run/docker.sock");
公共静态DockerClient CreateInstance()
{
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
返回新的DockerClientConfiguration(defaultWindowsDockerEngineUri).CreateClient();
其他的
返回新的DockerClientConfiguration(defaultLinuxDockerEngineUri).CreateClient();
}
}
}
命名空间关系.Promotion.Applier.IntegrationTest
{
公共类CustomWebApplicationFactory:WebApplicationFactory,其中TStartup:class
{
私有只读DockerClient DockerClient;
私有只读PromotionContainer PromotionContainer;
私有只读存储容器存储容器;
私有只读转换容器转换容器;
公共CustomWebApplicationFactory()
{
尝试
{
//Docker.DotNet的替代方案
// https://github.com/Deffiss/testenvironment-docker
dockerClient=DockerClientFactory.CreateInstance();
DockerContainerBase.CleanupOrientedContainers(dockerClient).Wait(300.Seconds());
如果(!dockerClient.Networks.ListNetworksAsync().Result.Select(n=>n.Name).Contains(“boti网络”))
{
var result=dockerClient.Networks.CreateNetworkAsync(新的Docker.DotNet.Models.NetworksCreateParameters()
{
Name=“boti网络”,
Driver=“桥”
}).结果;
}
promotionContainer=新的promotionContainer(图像名称:“升级引擎升级api”);
promotionContainer.Start(dockerClient).Wait(300.Seconds());
conversionContainer=新的conversionContainer(图像名称:“促销引擎转换api”);
conversionContainer.Start(dockerClient).Wait(300.Seconds());
storeContainer=新的storeContainer(“促销引擎商店api”);
storeContainer.Start(dockerClient).Wait(300.Seconds());
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
投
}
}
受保护的覆盖IWebHostBuilder CreateWebHostBuilder()
{
返回base.CreateWebHostBuilder().UseEnvironment(“Docker”);
}
受保护的覆盖无效处置(bool-itissafetoalsoferemanagedobjects)
{
如果(!Itissafetoalsoferemanagedobjects)返回;
promotionContainer.Remove(dockerClient).Wait(300.Seconds());
conversionContainer.Remove(dockerClient).Wait(300.s());
storeContainer.Remove(dockerClient).Wait(300.Seconds());
dockerClient.Dispose();
基础。处置(需要的物品的安全性);
}
}
}

您是否在本地环境中成功地做到了这一点?在将其迁移到microsoft hosted agent之前,您可以尝试在本地环境中运行它。它正在我的开发计算机上运行。阅读Ms Hosted Agent文档,似乎可以启动容器,因为Docker是从Windows映像预安装的。但我不知道正确的命名管道地址是什么。