如何从 java 级别创建 mysql 转储 docker 图像?

How to create mysql dump of docker image from java level?

我需要从 java 级别创建 docker 数据库的备份。使用 https://github.com/docker-java/docker-java 应该是可能的。我需要 运行 这个命令:

docker exec config_mysql_1 /usr/bin/mysqldump -u root --password=root SERVER > backup.sql

我这样试过:

DockerClient dockerClient = DockerClientBuilder.getInstance().build();
    Container container = dockerClient.listContainersCmd()
        .withNameFilter(Collections.singleton("mysql_1")).exec().get(0);

ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
        .withCmd("/usr/bin/mysqldump", "-u", "root", "--password=root", "SERVER", ">", "backup.sql").exec(); 

但没有创建任何内容。

你必须运行你的命令。

完整示例:

确保您的 mysql 已启动:

$ docker run --name mysql314 -e MYSQL_ROOT_PASSWORD=xxxx -d mysql
...
$ docker ps
CONTAINER ID   IMAGE ...
6ca86c54f335   mysql ...

运行:

DockerClientConfig standard = DefaultDockerClientConfig.createDefaultConfigBuilder().build();
DockerHttpClient httpClient = new OkDockerHttpClient.Builder().dockerHost(standard.getDockerHost()).sslConfig(standard.getSSLConfig()).build();
DockerClient dockerClient = DockerClientImpl.getInstance(standard, httpClient);
Container container = dockerClient.listContainersCmd().withNameFilter(Collections.singleton("mysql314")).exec().get(0);

ExecCreateCmdResponse execCreateCmdResponse = dockerClient
        .execCreateCmd(container.getId())
        .withPrivileged(true)
        .withAttachStdout(true)
        .withAttachStderr(true)
        .withCmd("/usr/bin/mysqldump", "-u", "root", "--password=xxxx", "--all-databases", "--result-file=/tmp/backup314.sql")
        .exec();

dockerClient.execStartCmd(execCreateCmdResponse.getId())
        .exec(new ExecStartResultCallback(System.out, System.err))
        .awaitCompletion();

InspectExecResponse rs = dockerClient.inspectExecCmd(execCreateCmdResponse.getId()).exec();
System.out.println("Exit Code: " + rs.getExitCodeLong());

确认结果

$ docker exec -it mysql314 bash
root@6ca86c54f335:/# head -n 1 /tmp/backup314.sql 
-- MySQL dump 10.13  Distrib 8.0.26, for Linux (x86_64)

执行以下语句:

ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
        .withCmd("/usr/bin/mysqldump", "-u", "root", "-p", "root", "SERVER", ">", "backup.sql").exec();

最终会将您的 MySQL 数据库转储写入容器临时层(假设容器 mysql_1 已经启动并且其 id 已成功检索)。

要检索数据库备份文件,您必须将一个卷装载到您的 docker 容器,以便您的备份文件被写入您的本地主机,或者使用 #DockerClient#copyArchiveFromContainerCmd:

InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "backup.sql").exec();

我建议将备份文件写入确定的绝对路径:

DockerClient dockerClient = DockerClientBuilder.getInstance().build();
Container container = dockerClient.listContainersCmd().withNameFilter(Collections.singleton("mysql_1")).exec().get(0);

ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
        .withCmd("/usr/bin/mysqldump", "-u", "root", "-p", "root", "SERVER", ">", "/backup.sql")
        .withTty(true)
        .withAttachStdout(true)
        .withAttachStderr(true)
        .exec();
InputStream dbDumpInputStream =  dockerClient.copyArchiveFromContainerCmd(container.getId(), "/backup.sql").exec();
// handle the `dbDumpInputStream` as per your need