Testcontainers报错绑定源路径不存在?多段尝试代码求解决方案
问题描述
我尝试使用Testcontainers运行Postgres容器,以下是我的代码:
func createContainer(ctx context.Context) (testcontainers.Container, *gorm.DB, string, error) { var env = map[string]string{ "POSTGRES_PASSWORD": DbPass, "POSTGRES_USER": DbUser, "POSTGRES_DB": DbName, } var port = "5432/tcp" path := `C:/Desktop/Folder/golang/TgBotReminder/internal/db/postgresql/migration/notes.sql` req := testcontainers.GenericContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ Image: "postgres:latest", ExposedPorts: []string{port}, Env: env, WaitingFor: wait.ForLog("database system is ready to accept connections"), SkipReaper: true, Mounts: testcontainers.Mounts( testcontainers.BindMount(path, "/docker-entrypoint-initdb.d"), ), }, Started: true, } ...
我指定的path路径实际存在,但却收到错误:Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /pipe/docker_engine: creating reaper failed: failed to create container。即使注释挂载相关代码,仍会出现该错误。
请问如何解决该问题?另外,path变量中写入文件名“notes.sql”是否正确?还是仅需填写目录路径?
更新1
我刚尝试了以下代码:
container, err := tspostgres.RunContainer(ctx, testcontainers.WithImage("postgres:latest"), tspostgres.WithInitScripts(filepath.Join(".", "test_migration", "notes.sql")), tspostgres.WithDatabase("test-db"), tspostgres.WithUsername("postgres"), tspostgres.WithPassword("postgres"), testcontainers.WithWaitStrategy( wait.ForLog("database system is ready to accept connections"). WithOccurrence(2).WithStartupTimeout(5*time.Second)), ) if err != nil { log.Fatal(err) }
仍出现相同错误
更新2
我还尝试了这段代码:
path := `/${PWD}/desktop/folder/golang/tgbotreminder/internal/db/postgresql/migration/notes.sql` target := "/docker-entrypoint-initdb.d/" ... Mounts: testcontainers.ContainerMounts{ testcontainers.ContainerMount{ Source: testcontainers.GenericBindMountSource{ HostPath: path, }, Target: testcontainers.ContainerMountTarget(target), }, },
依然无法解决 :(
更新3
我的另一次尝试:
Mounts: testcontainers.Mounts(testcontainers.ContainerMount{ Source: testcontainers.GenericBindMountSource{ HostPath: path, }, Target: testcontainers.ContainerMountTarget(target), }),
还是不行
解决方案
1. 解决核心的 /pipe/docker_engine 路径问题
这个错误和SQL文件挂载无关,是Windows环境下Testcontainers与Docker交互的配置问题:
- 打开Docker Desktop设置,进入General标签,勾选
Expose daemon on tcp://localhost:2375 without TLS,重启Docker Desktop - 设置系统环境变量:
DOCKER_HOST=tcp://localhost:2375TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock
2. SQL文件挂载的正确方式
- 挂载单个SQL文件时,目标可以写目录(Postgres会自动执行目录下所有
.sql文件),也可以直接指定文件路径(比如/docker-entrypoint-initdb.d/notes.sql),两种写法都合法 - Windows路径注意事项:
不要直接用C:/开头的格式,建议用filepath.Abs()获取标准绝对路径,避免格式兼容问题:import "path/filepath" // ... absPath, err := filepath.Abs("./internal/db/postgresql/migration/notes.sql") if err != nil { return nil, nil, "", err } - 使用
tspostgres.WithInitScripts()时,只需传入正确的相对/绝对路径即可,该方法会自动处理挂载逻辑,无需手动配置Mounts
3. 简化后的可用代码示例
import ( "context" "log" "path/filepath" "time" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/modules/postgres" "github.com/testcontainers/testcontainers-go/wait" ) func createContainer(ctx context.Context) (*postgres.PostgresContainer, error) { absScriptPath, err := filepath.Abs("./internal/db/postgresql/migration/notes.sql") if err != nil { return nil, err } container, err := postgres.RunContainer(ctx, testcontainers.WithImage("postgres:15-alpine"), // 建议指定具体版本而非latest postgres.WithInitScripts(absScriptPath), postgres.WithDatabase("test-db"), postgres.WithUsername("postgres"), postgres.WithPassword("postgres"), testcontainers.WithWaitStrategy( wait.ForLog("database system is ready to accept connections"). WithOccurrence(2).WithStartupTimeout(10*time.Second)), ) return container, err }
内容的提问来源于stack exchange,提问作者pizhlo
相关产品推荐
相关产品推荐

