Search code examples
c#dockerdockerfilexunittestcontainers

Cannot reach host.docker.internal in Github Actions


My integration tests using the TestContainers package run just fine locally on macOS. However, they don't succeed in GitHub Actions, because host.docker.internal isn't available there.

What's an alternative? I've tried the Docker Host IP address, which is 172.17.0.1. However, this isn't working either.

Example of setting up a container with my own image:

public async Task<IContainer> StartPostServiceContainerAsync(IContainer postgresContainer,
    IContainer rabbitmqContainer)
{
    var postgresPort = postgresContainer.GetMappedPublicPort(5432);
    var rabbitmqPort = rabbitmqContainer.GetMappedPublicPort(5672);

    var container = new ContainerBuilder()
        .WithImage("mydockerhubname/postservice:latest")
        .WithPortBinding(8080, true)
        .WithEnvironment("ConnectionStrings__PostsConn",
            $"Server=host.docker.internal;Port={postgresPort};Database=postgres;User Id=postgres;Password=postgres;")
        .WithEnvironment("RabbitMQHost", "host.docker.internal")
        .WithEnvironment("RabbitMQPort", rabbitmqPort.ToString())
        .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(8080))
        .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("Now listening on"))
        .DependsOn(postgresContainer)
        .DependsOn(rabbitmqContainer)
        .Build();

    await container.StartAsync();
    _containers["postservice"] = container;
    return container;
}

Example test:

[Fact]
public async Task Can_Call_Get_Posts_Endpoint()
{
    // Arrange
    var postgresContainer = await _fixture.StartPostgresContainerAsync();
    var rabbitmqContainer = await _fixture.StartRabbitMQContainerAsync();
    var postServiceContainer = await _fixture.StartPostServiceContainerAsync(postgresContainer, rabbitmqContainer);

    var postsServicePort = postServiceContainer.GetMappedPublicPort(8080);

    var httpClient = new HttpClient();
    var requestUri = new UriBuilder(
        Uri.UriSchemeHttp,
        postServiceContainer.Hostname,
        postsServicePort,
        "api/posts"
    ).Uri;

    // Act
    var response = await httpClient.GetAsync(requestUri);
    response.EnsureSuccessStatusCode();

    // Assert
    var content = await response.Content.ReadAsStringAsync();
    Assert.Equal("[]", content);
}

How can I fix this?


Solution

  • The issue has been resolved by using .withNetwork and . withNetworkAliases

    https://java.testcontainers.org/features/networking/

        public async Task<IContainer> StartPostgresContainerAsync()
        {
            var container = new ContainerBuilder()
                .WithImage("postgres:latest")
                .WithEnvironment("POSTGRES_USER", "postgres")
                .WithEnvironment("POSTGRES_PASSWORD", "postgres")
                .WithEnvironment("POSTGRES_DB", "postgres")
                .WithNetwork(_network)
                .WithNetworkAliases("postgres")
                .WithPortBinding(5432, true)
                .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(5432))
                .WithWaitStrategy(Wait.ForUnixContainer()
                    .UntilMessageIsLogged("database system is ready to accept connections"))
                .Build();
    
            await container.StartAsync();
            _containers["postgres"] = container;
    
            return container;
        }
    
            var container = new ContainerBuilder()
                .WithImage("mydockerhubname/postservice:latest")
                .WithNetwork(_network)
                .WithPortBinding(8080, true)
                .WithEnvironment("ConnectionStrings__PostsConn",
                    $"Server=postgres;Port=5432;Database=postgres;User Id=postgres;Password=postgres;")
                .WithEnvironment("RabbitMQHost", "rabbitmq")
                .WithEnvironment("RabbitMQPort", "5672")
                .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(8080))
                .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("Now listening on"))
                .DependsOn(postgresContainer)
                .DependsOn(rabbitmqContainer)
                .Build();