You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TestContainer-go中运行init-mongo.js脚本

在Testcontainers-Go中部署带用户认证的MongoDB

问题背景

之前通过Docker Compose部署MongoDB时,挂载init-mongo.js脚本自动创建认证用户,运行正常:

Docker Compose配置

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

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

现在需要在Golang项目中用Testcontainers部署MongoDB,但Testcontainers-Go不支持BindMounts字段,询问如何运行初始化脚本或创建用户密码。

解决方案

方法1:用Files字段挂载初始化脚本

Testcontainers-Go提供Files字段,可将本地文件复制到容器指定路径,替代BindMount功能。MongoDB启动时会自动执行/docker-entrypoint-initdb.d/目录下的脚本,代码示例:

package main

import (
	"context"
	"testcontainers-go/testcontainers"
)

func main() {
	ctx := context.Background()

	mongodbContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
		ContainerRequest: testcontainers.ContainerRequest{
			Image:        "mongo:6",
			ExposedPorts: []string{"27017/tcp"},
			Files: []testcontainers.ContainerFile{
				{
					HostFilePath:      "./init-mongo.js",
					ContainerFilePath: "/docker-entrypoint-initdb.d/init-mongo.js",
					FileMode:          0644,
				},
			},
		},
		Started: true,
	})
	if err != nil {
		panic(err)
	}
	defer mongodbContainer.Terminate(ctx)

	// 获取容器映射端口,用于后续连接
	port, err := mongodbContainer.MappedPort(ctx, "27017/tcp")
	if err != nil {
		panic(err)
	}
	// 示例连接字符串:mongodb://myuser:123456@localhost:%d/trojai?authSource=admin
}

如果不想依赖本地文件,也可以直接通过Content字段传递脚本内容:

Files: []testcontainers.ContainerFile{
	{
		ContainerFilePath: "/docker-entrypoint-initdb.d/init-mongo.js",
		Content: []byte(`
			db = db.getSiblingDB('admin');
			db.createUser({
				user: "myuser",
				pwd: "123456",
				roles: [{ role: "readWrite", db: "trojai" }]
			});
		`),
		FileMode: 0644,
	},
},

方法2:通过MongoDB Go驱动直接创建用户

容器启动后,用Go驱动连接到MongoDB,直接执行创建用户的命令,无需依赖初始化脚本:

package main

import (
	"context"
	"testcontainers-go/testcontainers"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
	ctx := context.Background()

	mongodbContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
		ContainerRequest: testcontainers.ContainerRequest{
			Image:        "mongo:6",
			ExposedPorts: []string{"27017/tcp"},
		},
		Started: true,
	})
	if err != nil {
		panic(err)
	}
	defer mongodbContainer.Terminate(ctx)

	port, err := mongodbContainer.MappedPort(ctx, "27017/tcp")
	if err != nil {
		panic(err)
	}

	// 连接到admin数据库(未认证)
	clientOpts := options.Client().ApplyURI("mongodb://localhost:" + port.Port())
	client, err := mongo.Connect(ctx, clientOpts)
	if err != nil {
		panic(err)
	}
	defer client.Disconnect(ctx)

	// 创建用户
	adminDB := client.Database("admin")
	err = adminDB.CreateUser(ctx, mongo.User{
		Username: "myuser",
		Password: "123456",
		Roles: []mongo.Role{
			{Role: "readWrite", DB: "trojai"},
		},
	})
	if err != nil {
		panic(err)
	}
}

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:45:18