Search code examples
mongodbtestcontainers

How to run init-mongo.js in the TestContainer-go


Basically, I can use docker-compose to setup mongoDB, and during creating mongoDB, I have a script init-mongo.js to create a mongo user and passord for Authentication. All works well.

version: '3'
services:
  mongodb:
    image: mongo:latest
    container_name: my-mongodb
    ports:
      - "27017:27017"
    volumes:
      - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js
    networks:
      - mongodb-net

networks:
  mongodb-net:

init-mongo.js file as below

db = db.getSiblingDB('admin');
db.createUser({
  user: "myuser",
  pwd: "123456",
  roles: [
    { role: "readWrite", db: "trojai" }
  ]
});

Now I wan to to use TestContainer to setup this mongoDB in my Golang project, I try to use the following code to do that, seem "BindMounts" isn't supported by TestContainer.go.

    mongodbContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
        ContainerRequest: testcontainers.ContainerRequest{
            Image:        "mongo:6",
            ExposedPorts: []string{"27017"},
            //BindMounts: map[string]string{
            //  "...": "./init-mongo.js",
            //},
        },
        Started: true,
    })

Any ideas to how to run my init-mongo.js? Or is there any alternative for me to create user and password (because my init-mongo.js is to create user and password)?


Solution

  • You could use Volume mapping:

    req := ContainerRequest{
        Image: "alpine",
        Mounts: ContainerMounts{
            {
                Source: GenericVolumeMountSource{
                    Name: "test-volume",
                },
                Target: "/data",
            },
        },
    }
    

    or you can specify which files should be copied to the container before it starts:

    ContainerRequest: ContainerRequest{
                Image:        "nginx:1.17.6",
                ExposedPorts: []string{"80/tcp"},
                WaitingFor:   wait.ForListeningPort("80/tcp"),
                Files: []ContainerFile{
                    {
                        HostFilePath:      "./testdata/hello.sh",
                        ContainerFilePath: "/copies-hello.sh",
                        FileMode:          0o700,
                    },
                },
            },
    

    There's a bit more details in the docs about this: https://golang.testcontainers.org/features/files_and_mounts/

    There's also a MongoDB module for Testcontainers-go, so you don't need to fully roll it yourself using the lower level GenericContainer API. For example it can take care of the correct waiting strategy and some other details and provide you with additional convenience MongoDB specific API: https://golang.testcontainers.org/modules/mongodb/.