如何在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
相关产品推荐
相关产品推荐

