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

如何在TestContainers中为instantlinux/samba-dc容器传递密钥并解决启动权限问题?

如何在TestContainers中为instantlinux/samba-dc容器传递密钥并解决启动权限问题?

看起来你在把本地的Samba DC Docker Compose配置迁移到TestContainers时遇到了两个核心问题:密钥读取失败,以及容器启动时的权限和健康检查报错。我来帮你一步步梳理解决方法:

一、先解决密钥传递的核心问题

你的原Docker Compose用了Docker Secrets,但TestContainers默认不会自动处理Kubernetes格式的Secret文件,而且容器本身其实支持更简单的密码传递方式:

方式1:直接用环境变量传递明文密码(测试环境推荐)

这个Samba DC镜像支持直接通过ADMIN_PASSWORD环境变量设置管理员密码,不需要绕secret文件,这样在测试环境里更省心:

val ldapContainer = GenericContainer("instantlinux/samba-dc:latest")
    .withEnv("DOMAIN_ACTION", "provision")
    .withEnv("REALM", "my.company")
    .withEnv("ADMIN_PASSWORD", "superpassword") // 直接设置明文密码
    // 其他配置...

方式2:正确挂载本地密钥文件(如果坚持用secret文件)

如果一定要用secret文件,注意两个关键点:

  1. 容器期望/run/secrets/samba-admin-password文件里直接是明文密码,而不是你现在用的Kubernetes Secret格式(base64编码的yaml)。你需要创建一个纯文本文件,比如admin-password.txt,里面只写superpassword。
  2. 用TestContainers的文件挂载功能把这个文件映射到容器的指定路径:
val secretPathOnHost = "C:\\work\\MyApp\\docker\\admin-password.txt"
val secretPathInContainer = "/run/secrets/samba-admin-password"

val ldapContainer = GenericContainer("instantlinux/samba-dc:latest")
    .withEnv("DOMAIN_ACTION", "provision")
    .withEnv("REALM", "my.company")
    .withEnv("ADMIN_PASSWORD_SECRET", "samba-admin-password") // 告诉容器读取这个secret
    .withFileSystemBind(secretPathOnHost, secretPathInContainer, BindMode.READ_ONLY)
    // 其他配置...

二、解决容器启动的权限和健康检查问题

从你的日志来看,还有两个关键问题需要处理:

1. 添加必要的系统权限

Samba DC需要CAP_SYS_ADMIN权限才能正常初始化(原Docker Compose里也加了这个),你需要在TestContainers里添加这个能力:

.withCreateContainerCmdModifier { cmd ->
    cmd.hostConfig!!.withCapAdd("CAP_SYS_ADMIN")
}

2. 修复健康检查的bash缺失问题

这个容器的基础镜像没有安装bash,但TestContainers默认用bash执行健康检查命令,导致报错/bin/sh: /bin/bash: not found。你需要自定义健康检查,用sh来执行:

.withHealthCheck(
    HealthCheck.newInstance()
        .withTestCommand("sh -c \"nc -z localhost 389 || exit 1\"")
        .withInterval(Duration.ofSeconds(5))
        .withTimeout(Duration.ofSeconds(10))
        .withRetries(5)
)

三、完整的可运行代码示例

把上面的配置整合起来,最终的TestContainers代码应该是这样的:

@Testcontainers
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
class TestContainersBase {

    @Test
    fun testSambaContainer() {
        val ldapContainer = GenericContainer("instantlinux/samba-dc:latest")
            // 基础环境配置
            .withEnv("DOMAIN_ACTION", "provision")
            .withEnv("REALM", "my.company")
            .withEnv("ADMIN_PASSWORD", "superpassword") // 直接用环境变量传密码
            // 暴露必要端口
            .withExposedPorts(53, 88, 389)
            // 添加Samba需要的系统权限
            .withCreateContainerCmdModifier { cmd ->
                cmd.hostConfig!!.withCapAdd("CAP_SYS_ADMIN")
            }
            // 自定义健康检查,避免bash缺失问题
            .withHealthCheck(
                HealthCheck.newInstance()
                    .withTestCommand("sh -c \"nc -z localhost 389 || exit 1\"")
                    .withInterval(Duration.ofSeconds(5))
                    .withTimeout(Duration.ofSeconds(10))
                    .withRetries(5)
            )

        ldapContainer.start()
        println("Samba DC容器启动成功!")
        // 这里可以添加你的测试逻辑
        Thread.sleep(10000)
        ldapContainer.stop()
    }
}

四、额外注意事项

  • 如果你的测试需要持久化Samba的数据,可以添加临时卷绑定:.withFileSystemBind("本地路径", "/var/lib/samba", BindMode.READ_WRITE),不过测试环境一般用容器临时卷就足够了。
  • 日志里的Unable to determine the DomainSID警告可以忽略,这是容器初始化过程中的正常信息,不影响功能。
  • 确保你的Docker Desktop已经开启了必要的权限(比如文件共享,如果你用Windows的话)。

备注:内容来源于stack exchange,提问作者gstackoverflow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 16:03:13