尝试以编程方式 运行 容器时从 Docker 退出代码 125
Exit Code 125 from Docker when Trying to Run Container Programmatically
我正在尝试进行集成测试。在测试初始化阶段,我尝试从 docker 图像启动 Redis 服务器。
var p = new Process { StartInfo = new ProcessStartInfo("docker", "run --name redistest –p 6379:6379 redis")};
p.Start();
当我这样做时,进程以退出代码 125 退出。如果我注释掉这些行,在测试代码执行之前在测试中打一个断点,而不是从命令行 运行
docker run --name redistest -p 6379:6379 redis
测试 运行 在从断点继续时符合预期。 125 存在代码仅表示 docker run
失败,因此没有更多信息可以继续。
在命令行调用或 C# 调用之前,我确保没有名为 redistest
和
的容器
docker stop redistest
docker rm redistest
但行为上的差异仍然存在。所有这些 运行 docker 的尝试都以编程方式失败:
- 添加
-d
- 运行宁作为普通用户
- 运行 提升权限
- 运行来自测试
- 运行来自 .NET Framework 控制台应用程序
为什么 docker run
命令的编程进程创建会导致 docker 以 125 退出?
它以编程方式对某些图像有效,但对其他图像无效。
在 .NET Framework 中,UseShellExecute 默认处于启用状态。这会更改新进程的当前目录。
我无法找出无法 运行 容器的原因,事实上它确实发生在其他几个容器上。我仍在寻找答案,但这里有一个解决方法,以备不时之需。
博客postIntegration testing using a docker container describes the code you need to write to use the Docker.DotNet NuGet package, which is a client that interacts with the Docker SDK.
现在我可以将此代码放入集成测试夹具中:
[AssemblyInitialize]
public static async Task InitializeDockerContainers(TestContext testContext)
{
await DockerSupport.StartDockerContainer("my container", "redis", "4.0.5-alpine", 6379);
}
并将它与(我已经在工作的)stop
和 rm
命令结合起来,以允许在集成测试期间干净地创建和删除容器。
尽管这已经一个月了,但我最近也遇到了这个问题。从 运行 命令中删除 --name 后,它可以完美运行。我无法弄清楚为什么会这样,但我将其张贴在这里是为了让人们了解在哪些地方可能不需要指定名称。
我知道这是一个老问题,我显然来不及帮助原始发帖者了,但是由于在搜索 docker 或podman,我想我会添加另一个我发现没有提到的解决方法(应该适用于 podman 或 docker)。发布以防对其他人有帮助。
我必须感谢上面的答案,尤其是 TheECanyon 的答案,因为它们为我指明了正确的方向,并提到它与通过 --name
有关。就是说,这不是革命性的。这只是 Kit 答案的一个变体,而不是将删除委托给 docker/podman,而不需要在 code/script 中进行额外处理。话又说回来,他的答案或混合方法可能更适合处理古怪的情况。和其他人一样,我在使用该参数时遇到了这个错误,但我没有看到任何关于无法 运行 容器的常见错误,因为具有该名称的容器已经存在。可能是因为我 运行 从脚本中获取它。
到目前为止我没有看到提及并允许我保持 --name
参数只是手动删除现有容器(例如[docker|podman] rm <container-name>
) 然后将 --rm
参数添加到 运行 命令(例如 [docker|podman] run --rm
),这会导致容器在退出时被删除(实际上,您将重新创建容器在每个 运行 和 docker/podman 上都会在 stops/exits 时删除它)。如果出于某种原因您需要每个 运行 使用完全相同的容器,这可能不会起作用,但在我的情况下,所有 config/data/persistent 位都存储在已安装的卷上并在next 运行 无论如何,它工作得很好,包括在无根容器中。
这个解决方案对我来说比简单地删除名称更有效,因为删除名称会导致生成一个新的容器实例 每个 运行 但 没有清理旧的容器实例。如果您只需要在本地开发箱上执行 10 秒的 运行 没什么大不了的,但理论上这可能会随着时间的推移导致一些存储问题,特别是如果您正在执行 100 秒或 1000 秒的 运行 ]s,每个创建一个新的容器实例。
我正在尝试进行集成测试。在测试初始化阶段,我尝试从 docker 图像启动 Redis 服务器。
var p = new Process { StartInfo = new ProcessStartInfo("docker", "run --name redistest –p 6379:6379 redis")};
p.Start();
当我这样做时,进程以退出代码 125 退出。如果我注释掉这些行,在测试代码执行之前在测试中打一个断点,而不是从命令行 运行
docker run --name redistest -p 6379:6379 redis
测试 运行 在从断点继续时符合预期。 125 存在代码仅表示 docker run
失败,因此没有更多信息可以继续。
在命令行调用或 C# 调用之前,我确保没有名为 redistest
和
docker stop redistest
docker rm redistest
但行为上的差异仍然存在。所有这些 运行 docker 的尝试都以编程方式失败:
- 添加
-d
- 运行宁作为普通用户
- 运行 提升权限
- 运行来自测试
- 运行来自 .NET Framework 控制台应用程序
为什么 docker run
命令的编程进程创建会导致 docker 以 125 退出?
它以编程方式对某些图像有效,但对其他图像无效。
在 .NET Framework 中,UseShellExecute 默认处于启用状态。这会更改新进程的当前目录。
我无法找出无法 运行 容器的原因,事实上它确实发生在其他几个容器上。我仍在寻找答案,但这里有一个解决方法,以备不时之需。
博客postIntegration testing using a docker container describes the code you need to write to use the Docker.DotNet NuGet package, which is a client that interacts with the Docker SDK.
现在我可以将此代码放入集成测试夹具中:
[AssemblyInitialize]
public static async Task InitializeDockerContainers(TestContext testContext)
{
await DockerSupport.StartDockerContainer("my container", "redis", "4.0.5-alpine", 6379);
}
并将它与(我已经在工作的)stop
和 rm
命令结合起来,以允许在集成测试期间干净地创建和删除容器。
尽管这已经一个月了,但我最近也遇到了这个问题。从 运行 命令中删除 --name 后,它可以完美运行。我无法弄清楚为什么会这样,但我将其张贴在这里是为了让人们了解在哪些地方可能不需要指定名称。
我知道这是一个老问题,我显然来不及帮助原始发帖者了,但是由于在搜索 docker 或podman,我想我会添加另一个我发现没有提到的解决方法(应该适用于 podman 或 docker)。发布以防对其他人有帮助。
我必须感谢上面的答案,尤其是 TheECanyon 的答案,因为它们为我指明了正确的方向,并提到它与通过 --name
有关。就是说,这不是革命性的。这只是 Kit 答案的一个变体,而不是将删除委托给 docker/podman,而不需要在 code/script 中进行额外处理。话又说回来,他的答案或混合方法可能更适合处理古怪的情况。和其他人一样,我在使用该参数时遇到了这个错误,但我没有看到任何关于无法 运行 容器的常见错误,因为具有该名称的容器已经存在。可能是因为我 运行 从脚本中获取它。
到目前为止我没有看到提及并允许我保持 --name
参数只是手动删除现有容器(例如[docker|podman] rm <container-name>
) 然后将 --rm
参数添加到 运行 命令(例如 [docker|podman] run --rm
),这会导致容器在退出时被删除(实际上,您将重新创建容器在每个 运行 和 docker/podman 上都会在 stops/exits 时删除它)。如果出于某种原因您需要每个 运行 使用完全相同的容器,这可能不会起作用,但在我的情况下,所有 config/data/persistent 位都存储在已安装的卷上并在next 运行 无论如何,它工作得很好,包括在无根容器中。
这个解决方案对我来说比简单地删除名称更有效,因为删除名称会导致生成一个新的容器实例 每个 运行 但 没有清理旧的容器实例。如果您只需要在本地开发箱上执行 10 秒的 运行 没什么大不了的,但理论上这可能会随着时间的推移导致一些存储问题,特别是如果您正在执行 100 秒或 1000 秒的 运行 ]s,每个创建一个新的容器实例。