寻求Golang中Testcontainers的.withTmpFs等效实现方案
问题分析
你的代码存在两个核心问题:
- 手动重置了
hc.Mounts = []mount.Mount{},这会删除Testcontainers为WithInitScripts自动添加的挂载项,导致初始化脚本无法被挂载到容器内的/docker-entrypoint-initdb.d目录。 - 将Tmpfs直接挂载到
/docker-entrypoint-initdb.d,该目录会被Tmpfs临时文件系统覆盖,即使挂载存在也无法生效。
可行解决思路
方案1:保留初始化脚本挂载,Tmpfs用于其他目录
如果你的Tmpfs需求不需要作用于/docker-entrypoint-initdb.d,可以修改Tmpfs目标目录,同时移除重置Mounts的代码:
pgContainer, err := postgres.Run(ctx, "postgres:15.3-alpine", testcontainers.WithEnv(env), testcontainers.WithHostConfigModifier(func(hc *container.HostConfig) { hc.CgroupnsMode = "host" // 将Tmpfs挂载到其他临时存储目录,比如/tmp hc.Tmpfs = map[string]string{ "/tmp": "rw", } // 不要重置Mounts,保留Testcontainers自动添加的初始化脚本挂载 }), postgres.WithInitScripts(filepath.Join("..", "testdata", "init-db.sql")), testcontainers.WithWaitStrategy( wait.ForLog("database system is ready to accept connections"). WithOccurrence(2).WithStartupTimeout(5*time.Second)), )
方案2:复制初始化脚本到Tmpfs目录(适合必须将Tmpfs用于/docker-entrypoint-initdb.d的场景)
放弃WithInitScripts,改用WithCopyFileToContainer在容器启动前将脚本复制到Tmpfs目录:
// 先读取本地初始化脚本内容 scriptPath := filepath.Join("..", "testdata", "init-db.sql") scriptContent, err := os.ReadFile(scriptPath) if err != nil { // 处理文件读取错误 } pgContainer, err := postgres.Run(ctx, "postgres:15.3-alpine", testcontainers.WithEnv(env), testcontainers.WithHostConfigModifier(func(hc *container.HostConfig) { hc.CgroupnsMode = "host" hc.Tmpfs = map[string]string{ "/docker-entrypoint-initdb.d": "rw", } }), // 将脚本复制到容器内的Tmpfs目录 testcontainers.WithCopyFileToContainer( testcontainers.NewFileToContainer("/docker-entrypoint-initdb.d/init-db.sql", scriptContent, 0644), ), testcontainers.WithWaitStrategy( wait.ForLog("database system is ready to accept connections"). WithOccurrence(2).WithStartupTimeout(5*time.Second)), )
方案3:自定义启动命令复制脚本
通过自定义启动命令,先将脚本从宿主机挂载目录复制到Tmpfs目录,再启动Postgres:
pgContainer, err := postgres.Run(ctx, "postgres:15.3-alpine", testcontainers.WithEnv(env), testcontainers.WithHostConfigModifier(func(hc *container.HostConfig) { hc.CgroupnsMode = "host" hc.Tmpfs = map[string]string{ "/docker-entrypoint-initdb.d": "rw", } // 挂载本地测试数据目录到容器临时位置 hc.Mounts = append(hc.Mounts, mount.Mount{ Type: "bind", Source: filepath.Join("..", "testdata"), Target: "/tmp/testdata", }) }), // 自定义启动流程:复制脚本到Tmpfs目录后启动Postgres testcontainers.WithCommand( "/bin/sh", "-c", "cp /tmp/testdata/init-db.sql /docker-entrypoint-initdb.d/ && docker-entrypoint.sh postgres", ), testcontainers.WithWaitStrategy( wait.ForLog("database system is ready to accept connections"). WithOccurrence(2).WithStartupTimeout(5*time.Second)), )
内容的提问来源于stack exchange,提问作者Sunfile
相关产品推荐
相关产品推荐

