testcontainers:如何修复绑定源路径不存在的问题

huangapple go评论87阅读模式
英文:

testcontainers: how to fix bind source path does not exist

问题

我正在尝试使用testcontainers运行一个容器。这是我的代码:

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,
	}
...

我在路径变量中提到的目录是存在的。但是我得到了错误: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。即使我注释掉了带有Mounts的行,我仍然会得到这个错误。如何修复它?另外,在路径变量中输入文件名("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),
				},
			},

还是没有成功 testcontainers:如何修复绑定源路径不存在的问题

更新3

这是我另一次尝试的代码:

Mounts: testcontainers.Mounts(testcontainers.ContainerMount{
                Source: testcontainers.GenericBindMountSource{
                        HostPath: path,
                },
                Target: testcontainers.ContainerMountTarget(target),
        }),

它也不起作用。

英文:

I'm trying to run a container using testcontainers. Here is my code:

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,
	}
...

The directory I've mentioned in the path variable exists. But I got the error: 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.
I got this error even if I comment lines with Mounts.
How to fix it? And also is it correct to type filename in the path variable ("notes.sql")? Or should I only type the directory here?

Thank you in advance

Update 1

I also tried this code right now:

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)
	}

got the same error

Update 2

Here is another piece of code I've tried:

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),
				},
			},

No luck again testcontainers:如何修复绑定源路径不存在的问题

Update 3

Here is my another attempt:

Mounts: testcontainers.Mounts(testcontainers.ContainerMount{
                Source: testcontainers.GenericBindMountSource{
                        HostPath: path,
                },
                Target: testcontainers.ContainerMountTarget(target),
        }),

It also doesn't work

答案1

得分: 2

似乎问题出在图像Ryuk和一些硬编码的值上,这些值与Windows不兼容。

testcontainers-go目前不支持“Windows容器”:它有一些硬编码的默认值,没有考虑到Windows容器的可能性。

请参考https://github.com/testcontainers/testcontainers-go/issues/948

英文:

It seems like the issue is with the image Ryuk and some hard-coded values which is not compatible with windows.
> testcontainers-go currently doesn't support "Windows containers": it has some hard-coded defaults that don't consider the possibility of Windows containers.

See https://github.com/testcontainers/testcontainers-go/issues/948

答案2

得分: 1

我在我的机器上遇到了相同的问题。完整的错误消息如下:

2023/07/11 12:15:35 github.com/testcontainers/testcontainers-go - 连接到docker:
  服务器版本:20.10.14
  API版本:1.41
  操作系统:Docker Desktop
  总内存:7912 MB
2023/07/11 12:15:35 🐳 为镜像docker.io/testcontainers/ryuk:0.5.1创建容器
panic: 守护程序的错误响应:类型为"bind"的挂载配置无效:绑定源路径不存在:/pipe/docker_engine:创建reaper失败:无法创建容器

正如@pratheesh-pc指出的那样,这意味着无法从镜像docker.io/testcontainers/ryuk:0.5.1创建容器。这与您要创建的自己容器的挂载配置无关。我认为@pratheesh-pc回答中提供的链接是针对Windows上的Windows容器(WCOW),但我在运行Windows上的Linux容器(LCOW)时遇到了这个问题。

一个解决方法是禁用reaper。实际上,您在代码中设置了SkipReaper: true,并且您的意图是禁用reaper。问题是,从github.com/testcontainers/testcontainers-go@v0.20.0开始,SkipReaper被完全忽略了,您必须使用以下方法之一来禁用它:the following approaches

  1. .testcontainers.properties文件中添加ryuk.disabled=true。在Windows上,文件的完整路径是C:/Users/%my_username%/.testcontainers.properties
  2. 设置TESTCONTAINERS_RYUK_DISABLED=true环境变量。此方式优先于属性文件。
英文:

I have encountered the same issue on my machine. The full error message is:

2023/07/11 12:15:35 github.com/testcontainers/testcontainers-go - Connected to docker:
  Server Version: 20.10.14
  API Version: 1.41
  Operating System: Docker Desktop
  Total Memory: 7912 MB
2023/07/11 12:15:35 🐳 Creating container for image docker.io/testcontainers/ryuk:0.5.1
panic: 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

As pointed out by @pratheesh-pc, It means that it failed to create the container from the image docker.io/testcontainers/ryuk:0.5.1. It has nothing to do with the mounts configuration of your own container that you want to create. I think the link provided in @pratheesh-pc's answer is for Windows Container on Windows (WCOW), but I encountered the issue when running Linux Container on Windows (LCOW).

A workaround is to disable the reaper. In fact, you have set SkipReaper: true in your code and you meant to disable the reaper. The problem is, from github.com/testcontainers/testcontainers-go@v0.20.0, SkipReaper is totally ignored, and you have to disable it with one of the following approaches:

  1. adding ryuk.disabled=true to the .testcontainers.properties file. On Windows, the full path of the file is C:/Users/%my_username%/.testcontainers.properties.
  2. setting the TESTCONTAINERS_RYUK_DISABLED=true environment variable. This manner takes precedence over the properties file.

答案3

得分: 0

似乎问题出在 Mounts 部分,请尝试:

Mounts: []testcontainers.Mount{
    {
        Source: path,
        Target: "/docker-entrypoint-initdb.d/notes.sql",
        Type:   testcontainers.BindMountType,
    },
},

在指定绑定挂载的源路径时,应提供完整的文件路径,包括文件名本身。因此,在路径变量中包含文件名("notes.sql")是正确的。

英文:

it seems like the issue lies with the Mounts try:

Mounts: []testcontainers.Mount{
            {
                Source: path,
                Target: "/docker-entrypoint-initdb.d/notes.sql",
                Type:   testcontainers.BindMountType,
            },
        },

when specifying the source path for a bind mount, you should provide the complete path to the file, including the file name itself. So, it is correct to include the filename ("notes.sql") in the path variable.

答案4

得分: 0

已解决

C:/Users/%my_username%/目录下创建了一个名为.testcontainers.properties的文件,并在其中写入了ryuk.disabled=true

英文:

Solved

created a file .testcontainers.properties in the C:/Users/%my_username%/ and wrote there: ryuk.disabled=true

huangapple
  • 本文由 发表于 2023年7月11日 00:45:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76655770.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定