Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MongoDb Replica Set Mode Exits #538

Closed
the-avid-engineer opened this issue Jul 31, 2022 · 5 comments
Closed

MongoDb Replica Set Mode Exits #538

the-avid-engineer opened this issue Jul 31, 2022 · 5 comments
Labels
enhancement New feature or request
Milestone

Comments

@the-avid-engineer
Copy link
Contributor

Describe the bug
It appears that the MongoDb container cannot be switched to replica set mode - the container just exits after completing initialization. When I run an equivalent setup using docker-compose.yml (albeit not using resource reaper), I do not have the issue - the container keeps running just fine and replica set mode is available for usage.

To Reproduce
Make an xunit test.

Add the following file, with paths relative to the test project's csproj file, and configure the csproj to always copy this file to output.

./DockerEntrypoints/MongoDb/Init/init.js

rs.initiate(
    {
        _id: "repro",
        version: 1,
        members: [
            {_id: 0, host: "127.0.0.1:27017"}
        ]
    }
);
    <ItemGroup>
      <None Update="DockerEntrypoints\**\*">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      </None>
    </ItemGroup>

Create this fixture and inject it into a test.

public class DatabaseContainerFixture : IAsyncLifetime
{
    private static readonly MongoDbTestcontainerConfiguration _mongoDbConfiguration = new("mongo:5.0.9")
    {
        Database = "repro",
        Username = "repro",
        Password = "repro"
    };
    public MongoDbTestcontainerConfiguration MongoDbConfiguration => _mongoDbConfiguration;

    public MongoDbTestcontainer MongoDbContainer { get; } = new TestcontainersBuilder<MongoDbTestcontainer>()
        .WithDatabase(_mongoDbConfiguration)
        .WithBindMount(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DockerEntrypoints", "MongoDb", "Init"), "/docker-entrypoint-initdb.d/")
        .WithCommand("--replSet", "repro")
        .Build();

    public async Task InitializeAsync()
    {
        await MongoDbContainer.StartAsync();
    }

    public async Task DisposeAsync()
    {
        await MongoDbContainer.DisposeAsync();
    }
}

The following error (or similar) is thrown in InitializeAsync:

Docker.DotNet.DockerApiException: 'Docker API responded with status code=Conflict, response={"message":"Container 6dbd85acf7896537f92122901013146c988682581c3119a8932ae5bcf24048f6 is not running"}

The task exists, and if you look into the logs, the last line will be:

MongoDB init process complete; ready for start up.

Expected behavior
If you run an equivalent setup using docker-compose, the container does not exit - it keeps going.

version: "3.3"
services:
  mongodb:
    image: mongo:5.0.9
    ports:
      - "27017:27017"
    volumes:
      - ./DockerEntrypoints/MongoDb/Init:/docker-entrypoint-initdb.d/
    command: --replSet repro

Desktop (please complete the following information):
4.3.2 / v20.10.11 (Docker Version?)

Additional context
Replica set mode allows for MongoDb transactions. It's very critical to have transactions in my tests.

@HofmeisterAn
Copy link
Collaborator

HofmeisterAn commented Jul 31, 2022

It looks like that the container does not start properly (it exits almost immediately). With the example above, I get the following error:

[...]
BadValue: security.keyFile is required when authorization is enabled with replica sets
try 'mongod --help' for more information
[...]

MongoDB init process complete; ready for start up.

If I create the security key file, set the right permissions and assign the mongodb user and group to it, the container starts:

public sealed class GitHub : IAsyncLifetime
{
  private static readonly string Source = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

  private static readonly string Destination = "/docker-entrypoint-initdb.d";

  private static readonly string SecurityKeyFilePath = $"{Destination}/replica.key";

  private readonly TestcontainerDatabase mongoDb = new TestcontainersBuilder<MongoDbTestcontainer>()
    .WithDatabase(new MongoDbTestcontainerConfiguration { Database = "GitHub", Username = "mongodb", Password = "mongodb" })
    .WithBindMount(Source, Destination)
    .WithEntrypoint("/bin/sh", "-c", $"chown 999:999 {SecurityKeyFilePath} && mongod")
    .WithCommand("--replSet", "repro")
    .Build();

  [Fact]
  public Task Issue538()
  {
    return Task.CompletedTask;
  }

  public Task InitializeAsync()
  {
    return this.mongoDb.StartAsync();
  }

  public Task DisposeAsync()
  {
    return this.mongoDb.DisposeAsync().AsTask();
  }
}

Is your security key file setup properly?

@HofmeisterAn HofmeisterAn added the question Have you tried our Slack workspace (https://testcontainers.slack.com)? label Jul 31, 2022
@the-avid-engineer
Copy link
Contributor Author

the-avid-engineer commented Jul 31, 2022

Interesting, I didn't even know about that setting / haven't had to configure it up to this point using docker compose - I will take a look, thank you 😀

@the-avid-engineer
Copy link
Contributor Author

the-avid-engineer commented Jul 31, 2022

I tried fiddling with the security key but that was painful.. Instead I just removed the username/password, because the security key is not required if auth isn't set up. The only issue is that the connection string has the auth component even though there's no username/password

mongodb://:@localhost:...

Instead of

mongodb://localhost:...

Easy enough to fix in my code with a string replacement, though I wonder if the package should just not include this component of the connection string if Username and Password are null?

Either way, thank you for the help! :)

@HofmeisterAn
Copy link
Collaborator

I wonder if the package should just not include this component of the connection string if Username and Password are null?

OC, we can change the behavior. Modules heavily rely on contribution, I'm not a MongoDB expert. Supporting more use cases would be great. If you have any improvement in mind, a contribution is more than welcome.

@the-avid-engineer
Copy link
Contributor Author

#547

HofmeisterAn added a commit that referenced this issue Aug 2, 2022
@HofmeisterAn HofmeisterAn added this to the 2.2.0 milestone Aug 2, 2022
@HofmeisterAn HofmeisterAn added enhancement New feature or request and removed question Have you tried our Slack workspace (https://testcontainers.slack.com)? labels Aug 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants