如何从多阶段 docker 构建连接到 BitBucket 服务容器?

How do I connect to a BitBucket service containers from a multi staged docker build?

在使用其他托管 CI 解决方案后,这似乎很简单,但使用 BitBucket 时,它似乎并没有发挥作用。我猜这是因为构建步骤是 运行 在 docker 容器中并且 docker CLI 刚刚安装到那个容器中?

但是,我想知道是否有办法让它工作?

我们有一个多阶段的 docker 构建,它运行一个构建,然后对数据库运行一组测试。下面是这个的简化版本。

FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["docker-build-problem-example.csproj", "./"]
RUN dotnet restore "docker-build-problem-example.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "docker-build-problem-example.csproj" -c Release -o /app/build

FROM build AS test
RUN dotnet test "docker-build-problem-example.csproj" -c Release

FROM test AS publish
RUN dotnet publish "docker-build-problem-example.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "docker-build-problem-example.dll"]

测试阶段运行以下示例测试,该测试仅查询 MongoDB 数据库。

public class UnitTest1
{
    [Fact]
    public async Task Test1()
    {
        var client = new MongoClient($"mongodb://{GetHostName()}");
        var database = client.GetDatabase("test");
        var collection = database.GetCollection<BsonDocument>("docs");

        var items = await collection.Find(Builders<BsonDocument>.Filter.Empty)
            .ToListAsync();

        Assert.Empty(items);
    }

    private string GetHostName()
    {
        return Environment.GetEnvironmentVariable("CI") is { }
            ? "127.0.0.1" : "host.docker.internal";
    }
}

上面使用 127.0.0.1 作为主机名,因为这是文档所说的使用,但是,这只是超时,不会连接。

有没有办法将这些容器连接在一起,以便它们可以交谈?

这是我的 bitbucket.yml 文件。

image: atlassian/default-image:2

pipelines:
  default:
    - step:
        name: 'Build and Test'
        services:
           - mongo
           - docker
        script:
           - docker ps
           - docker network ls
           - docker build .

definitions: 
  services: 
    mongo: 
      image: mongo

我在此处上传了一个 public 示例 - https://bitbucket.org/kev_bite/docker-build-problem-example/src/master/

这是管道构建 - https://bitbucket.org/kev_bite/docker-build-problem-example/addon/pipelines/home#!/results/5

我使用的完整流程是....

  1. 我启动了一个 postgres 数据库作为 bitbucket 管道中的一个容器。 (与您的 mongodb 服务相同)

  2. 然后我将 docker 主机的地址(使用 $BITBUCKET_DOCKER_HOST_INTERNAL 找到)环境变量传递给 docker 构建命令,如下所示

docker 构建 -t image_name 。 --build-arg DATABASE_SERVER=$BITBUCKET_DOCKER_HOST_INTERNAL

  1. 在docker文件中,DATABASE_SERVER被定义为一个ARG,即。 ARG DATABASE_SERVER

  2. 再次在 docker 文件中,然后我将该 ARG 映射到环境变量

ENV POSTGRES_ENDPOINT=$DATABASE_SERVER

  1. 我的测试代码,然后使用POSTGRES_ENDPOINT环境变量