Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Docker 配置Minio服务器以与Testcontainers一起使用_Docker_Minio_Testcontainers - Fatal编程技术网

Docker 配置Minio服务器以与Testcontainers一起使用

Docker 配置Minio服务器以与Testcontainers一起使用,docker,minio,testcontainers,Docker,Minio,Testcontainers,我的应用程序用于S3兼容的对象存储,我希望在集成测试中使用Minio docker映像 对于一些非常基本的测试,我使用minio/miniodocker映像运行一个GenericContainer,除了minio\u ACCESS\u KEY和minio\u SECRET\u KEY之外,没有其他配置。然后,我的测试使用Minio。这些工作很好,表现和预期的一样 但是对于其他集成测试,我需要在Mino中设置单独的用户。据我所知,用户只能使用添加到Minio,而没有Java客户端,只有Minio/

我的应用程序用于S3兼容的对象存储,我希望在集成测试中使用Minio docker映像

对于一些非常基本的测试,我使用
minio/minio
docker映像运行一个GenericContainer,除了
minio\u ACCESS\u KEY
minio\u SECRET\u KEY
之外,没有其他配置。然后,我的测试使用Minio。这些工作很好,表现和预期的一样

但是对于其他集成测试,我需要在Mino中设置单独的用户。据我所知,用户只能使用添加到Minio,而没有Java客户端,只有
Minio/mc
docker映像(服务器使用的
Minio/Minio
docker映像中没有
mc
CLI)

在命令行上,我可以像这样使用管理API:

$ docker run --interactive --tty --detach --entrypoint=/bin/sh --name minio_admin minio/mc
public void testAdminApi() throws Exception {
    GenericContainer mc = new GenericContainer("minio/mc")
            .withCommand("/bin/sh")
            .withCreateContainerCmdModifier(new Consumer<CreateContainerCmd>() {
                @Override
                public void accept(CreateContainerCmd cmd) {
                    cmd
                            .withAttachStdin(true)
                            .withStdinOpen(true)
                            .withTty(true);
                }
            });

    mc.start();
    log.info("mc is running: {}", mc.isRunning());

    String command = "mc";
    Container.ExecResult result = mc.execInContainer(command);
    log.info("Executing command '{}' returned exit code '{}' and stdout '{}'", command, result.getExitCode(), result.getStdout());

    assertEquals(0, result.getExitCode());
}
--interactive--tty
是一种让容器运行的技巧,因此我可以在以后运行如下命令:

$ docker exec --interactive --tty minio_admin mc admin user add ...
使用Testcontainers,我尝试执行以下操作:

$ docker run --interactive --tty --detach --entrypoint=/bin/sh --name minio_admin minio/mc
public void testAdminApi() throws Exception {
    GenericContainer mc = new GenericContainer("minio/mc")
            .withCommand("/bin/sh")
            .withCreateContainerCmdModifier(new Consumer<CreateContainerCmd>() {
                @Override
                public void accept(CreateContainerCmd cmd) {
                    cmd
                            .withAttachStdin(true)
                            .withStdinOpen(true)
                            .withTty(true);
                }
            });

    mc.start();
    log.info("mc is running: {}", mc.isRunning());

    String command = "mc";
    Container.ExecResult result = mc.execInContainer(command);
    log.info("Executing command '{}' returned exit code '{}' and stdout '{}'", command, result.getExitCode(), result.getStdout());

    assertEquals(0, result.getExitCode());
}

在花了几个小时摆弄这件事之后,我已经没有主意了。有人能帮忙吗?

您可以使用
mc
with command(“您的命令”)
运行一个一次性容器(使用
OneShotStartupCheckStrategy
),该容器与您正在运行的minio服务器连接到同一网络(请参阅)。

如@bsideup所建议,您可以使用一次性策略,即,如中所示。 UPD:增加了工作测试。知道这一点很重要

当容器启动时,它执行entrypoint+命令(这通常是Docker,与Testcontainers无关)

基本上,它在安装了mc的情况下运行image,并休眠1小时,这对于您的测试来说已经足够了。当它运行时,您可以执行命令等。完成后,它将被杀死。
您的minio容器可以位于同一网络中。

多亏了@glebsts和@bsideup,我才能够让集成测试正常工作。下面是如何添加用户的一个简单示例:

public class MinioIntegrationTest {

    private static final String ADMIN_ACCESS_KEY = "admin";
    private static final String ADMIN_SECRET_KEY = "12345678";
    private static final String USER_ACCESS_KEY = "bob";
    private static final String USER_SECRET_KEY = "87654321";

    private static GenericContainer minioServer;
    private static String minioServerUrl;

    @BeforeAll
    static void setUp() throws Exception {
        int port = 9000;
        minioServer = new GenericContainer("minio/minio")
                .withEnv("MINIO_ACCESS_KEY", ADMIN_ACCESS_KEY)
                .withEnv("MINIO_SECRET_KEY", ADMIN_SECRET_KEY)
                .withCommand("server /data")
                .withExposedPorts(port)
                .waitingFor(new HttpWaitStrategy()
                        .forPath("/minio/health/ready")
                        .forPort(port)
                        .withStartupTimeout(Duration.ofSeconds(10)));
        minioServer.start();

        Integer mappedPort = minioServer.getFirstMappedPort();
        Testcontainers.exposeHostPorts(mappedPort);
        minioServerUrl = String.format("http://%s:%s", minioServer.getContainerIpAddress(), mappedPort);

        // Minio Java SDK uses s3v4 protocol by default, need to specify explicitly for mc
        String cmdTpl = "mc config host add myminio http://host.testcontainers.internal:%s %s %s --api s3v4 && "
                + "mc admin user add myminio %s %s readwrite";
        String cmd = String.format(cmdTpl, mappedPort, ADMIN_ACCESS_KEY, ADMIN_SECRET_KEY, USER_ACCESS_KEY, USER_SECRET_KEY);

        GenericContainer mcContainer = new GenericContainer<>("minio/mc")
                .withStartupCheckStrategy(new OneShotStartupCheckStrategy())
                .withCreateContainerCmdModifier(containerCommand -> containerCommand
                        .withTty(true)
                        .withEntrypoint("/bin/sh", "-c", cmd));
        mcContainer.start();
    }

    @Test
    public void canCreateBucketWithAdminUser() throws Exception {
        MinioClient client = new MinioClient(minioServerUrl, ADMIN_ACCESS_KEY, ADMIN_SECRET_KEY);
        client.ignoreCertCheck();

        String bucketName = "foo";
        client.makeBucket(bucketName);
        assertTrue(client.bucketExists(bucketName));
    }

    @Test
    public void canCreateBucketWithNonAdminUser() throws Exception {
        MinioClient client = new MinioClient(minioServerUrl, USER_ACCESS_KEY, USER_SECRET_KEY);
        client.ignoreCertCheck();

        String bucketName = "bar";
        client.makeBucket(bucketName);
        assertTrue(client.bucketExists(bucketName));
    }

    @AfterAll
    static void shutDown() {
        if (minioServer.isRunning()) {
            minioServer.stop();
        }
    }
}
公共类小型集成测试{
私有静态最终字符串ADMIN\u ACCESS\u KEY=“ADMIN”;
私有静态最终字符串ADMIN\u SECRET\u KEY=“12345678”;
私有静态最终字符串USER\u ACCESS\u KEY=“bob”;
私有静态最终字符串USER_SECRET_KEY=“87654321”;
专用静态通用容器小型服务器;
私有静态字符串minioServerUrl;
@以前
静态void setUp()引发异常{
int端口=9000;
minioServer=新的通用容器(“minio/minio”)
.withEnv(“MINIO\u访问密钥”,ADMIN\u访问密钥)
.withEnv(“MINIO_SECRET_KEY”,ADMIN_SECRET_KEY)
.withCommand(“服务器/数据”)
.withExposedPorts(端口)
.waitingFor(新的HttpWaitingStrategy()
.forPath(“/minio/health/ready”)
.forPort(港口)
.具有启动超时(持续时间为秒(10));
minioServer.start();
整数mappedPort=minioServer.getFirstMappedPort();
exposeHostPorts(mappedPort);
minioServerUrl=String.format(“http://%s:%s”,minioServer.getContainerIpAddress(),mappedPort);
//Minio Java SDK默认使用s3v4协议,需要为mc显式指定
String cmdTpl=“mc配置主机添加myminio”http://host.testcontainers.internal:%s %s%s--api s3v4&“
+“mc管理员用户添加myminio%s%s读写”;
String cmd=String.format(cmdTpl、mappedPort、ADMIN\u ACCESS\u KEY、ADMIN\u SECRET\u KEY、USER\u ACCESS\u KEY、USER\u SECRET\u KEY);
GenericContainer mcContainer=新的GenericContainer(“minio/mc”)
.withStartupCheckStrategy(新的OneShotStartupCheckStrategy())
.WithCreateContainerCmd修改器(containerCommand->containerCommand)
.withTty(真)
.withEntrypoint(“/bin/sh”,“-c”,cmd));
mcContainer.start();
}
@试验
public void canCreateBucketWithAdminUser()引发异常{
MinioClient=新的MinioClient(minioServerUrl、管理员访问密钥、管理员密钥);
client.ignoreCertCheck();
字符串bucketName=“foo”;
client.makeBucket(bucketName);
assertTrue(client.bucketExists(bucketName));
}
@试验
public void canCreateBucketWithNonAdminUser()引发异常{
MinioClient=新的MinioClient(minioServerUrl、用户访问密钥、用户密钥);
client.ignoreCertCheck();
字符串bucketName=“bar”;
client.makeBucket(bucketName);
assertTrue(client.bucketExists(bucketName));
}
@毕竟
静态无效关机(){
if(minioServer.isRunning()){
minioServer.stop();
}
}
}

基本上,这种“睡眠”与您将容器分离并运行所做的相同。添加了一次性容器的示例。在我的机器上工作(tm)*@BeforeAll/!毕竟没有任何意义,因为testcontainers与@ClassRule配合得很好,您不需要手动清理*覆盖入口点-值得怀疑,所有这些都是因为将巨型超弦粘在一起;*从genericContainer复制硬编码常量是值得怀疑的*为什么实际上需要公开端口?描述了您可能需要它的情况,但在这里,minio和mc都在容器中运行,将它们放在同一个网络中可以更好地隔离它们,并且当您可以拥有内部IP时,您不需要依赖文本url;*您的minio在测试之间没有被清理,env是脏的。这可能会导致测试的相互依赖性,或太多的痛苦,例如添加不需要添加用户的测试
public class MinioIntegrationTest {

    private static final String ADMIN_ACCESS_KEY = "admin";
    private static final String ADMIN_SECRET_KEY = "12345678";
    private static final String USER_ACCESS_KEY = "bob";
    private static final String USER_SECRET_KEY = "87654321";

    private static GenericContainer minioServer;
    private static String minioServerUrl;

    @BeforeAll
    static void setUp() throws Exception {
        int port = 9000;
        minioServer = new GenericContainer("minio/minio")
                .withEnv("MINIO_ACCESS_KEY", ADMIN_ACCESS_KEY)
                .withEnv("MINIO_SECRET_KEY", ADMIN_SECRET_KEY)
                .withCommand("server /data")
                .withExposedPorts(port)
                .waitingFor(new HttpWaitStrategy()
                        .forPath("/minio/health/ready")
                        .forPort(port)
                        .withStartupTimeout(Duration.ofSeconds(10)));
        minioServer.start();

        Integer mappedPort = minioServer.getFirstMappedPort();
        Testcontainers.exposeHostPorts(mappedPort);
        minioServerUrl = String.format("http://%s:%s", minioServer.getContainerIpAddress(), mappedPort);

        // Minio Java SDK uses s3v4 protocol by default, need to specify explicitly for mc
        String cmdTpl = "mc config host add myminio http://host.testcontainers.internal:%s %s %s --api s3v4 && "
                + "mc admin user add myminio %s %s readwrite";
        String cmd = String.format(cmdTpl, mappedPort, ADMIN_ACCESS_KEY, ADMIN_SECRET_KEY, USER_ACCESS_KEY, USER_SECRET_KEY);

        GenericContainer mcContainer = new GenericContainer<>("minio/mc")
                .withStartupCheckStrategy(new OneShotStartupCheckStrategy())
                .withCreateContainerCmdModifier(containerCommand -> containerCommand
                        .withTty(true)
                        .withEntrypoint("/bin/sh", "-c", cmd));
        mcContainer.start();
    }

    @Test
    public void canCreateBucketWithAdminUser() throws Exception {
        MinioClient client = new MinioClient(minioServerUrl, ADMIN_ACCESS_KEY, ADMIN_SECRET_KEY);
        client.ignoreCertCheck();

        String bucketName = "foo";
        client.makeBucket(bucketName);
        assertTrue(client.bucketExists(bucketName));
    }

    @Test
    public void canCreateBucketWithNonAdminUser() throws Exception {
        MinioClient client = new MinioClient(minioServerUrl, USER_ACCESS_KEY, USER_SECRET_KEY);
        client.ignoreCertCheck();

        String bucketName = "bar";
        client.makeBucket(bucketName);
        assertTrue(client.bucketExists(bucketName));
    }

    @AfterAll
    static void shutDown() {
        if (minioServer.isRunning()) {
            minioServer.stop();
        }
    }
}