要从 Docker Hub 恢复包含数据的镜像并运行相应容器,可以按照以下简洁清晰的步骤进行操作:

1. 拉取最新镜像

首先,从 Docker Hub 拉取最新的镜像:

docker pull bluebro/blue_repository:wp_mysql-latest

2. 运行容器

使用该镜像启动一个新的容器:

docker run -d \
    -p 3306:3306 \
    --name wp_mysql \
    bluebro/blue_repository:wp_mysql-latest

3. 清理原有数据

在拷贝镜像中的数据前,确保清理原有的数据目录:

rm -rf /data/wordpress/wp_mysql

4. 拷贝数据

从运行的容器中拷贝数据到宿主机的指定目录:

docker cp wp_mysql:/var/lib/mysql /data/wordpress/wp_mysql

5. 移除原容器

为了避免混淆,清理掉刚才创建的容器:

docker rm -f wp_mysql

6. 重新映射数据卷并运行新容器

最后,使用本地数据卷重新启动容器,确保数据持久化:

docker run -d \
    -p 3306:3306 \
    --name wp_mysql \
    -v /data/wordpress/wp_mysql:/var/lib/mysql \
    bluebro/blue_repository:wp_mysql-latest

这个过程详细说明了如何从 Docker Hub 恢复一个包含数据的镜像,并正确配置容器以使用这些数据。请确保在执行数据拷贝和删除操作时小心谨慎,以防不慎丢失重要数据。

7. 问题:为什么要这么多步骤,我直接使用该镜像启动一个新的容器时,直接加上 -v 不可以吗?

在 Docker 中,当使用 -v 选项来挂载卷时,Docker 将宿主机的目录或数据卷挂载到容器的指定目录。如果这个挂载点在容器内已经包含了数据(如预装的 MySQL 数据库文件),这些数据会被宿主机目录的内容“遮盖”掉。如果宿主机的目录是空的,那么容器内该位置的数据将看起来像是“消失”了。

这就是为什么当使用 -v 指定卷映射时,容器中看似没有数据,而去掉 -v 选项后容器里就有数据的原因。下面是对这种情况的进一步解释和解决方法:

原因解释

  1. 挂载覆盖:当运行带有 -v /path/on/host:/var/lib/mysql 的命令时,Docker 会把宿主机的 /path/on/host 目录挂载到容器的 /var/lib/mysql 目录。如果宿主机的 /path/on/host 是空的,那么它将覆盖容器中的 /var/lib/mysql,导致容器看起来没有数据。
  2. 数据初始化:对于许多官方镜像,如 MySQL,容器的启动脚本会检查 /var/lib/mysql 是否为空,如果为空,它会进行数据库的初始化过程,创建新的数据库文件。但如果该目录通过 -v 被挂载并且为空,容器内的数据库初始化可能就不会执行,因为挂载目录覆盖了原有数据。

解决方法

  1. 提前准备数据:在运行容器之前,先在 /path/on/host 中放置必要的数据。例如,你可以先启动一个不带 -v 的容器,让它初始化数据,然后把这些数据复制到宿主机的指定目录下:
    docker run --name temp-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
    # 等待几分钟让MySQL初始化完成
    docker cp temp-mysql:/var/lib/mysql /path/on/host
    docker rm -f temp-mysql
  2. 使用正确的挂载点:确保挂载的宿主机目录是你想要的状态,如果需要预装数据,按照上述方法操作。
  3. 重新运行容器:使用准备好的数据目录重新运行你的容器:
    docker run -d \
    -p 3306:3306 \
    --name mysql \
    -e MYSQL_ROOT_PASSWORD=my-secret-pw \
    -v /path/on/host:/var/lib/mysql \
    mysql:tag

    这种方法不仅可以解决初始化问题,还可以更好地管理和备份数据。