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

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:2375
    • TESTCONTAINERS_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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:55:58