一. 基础知识
在 Docker 中,推送镜像到 Docker Hub 是一个常见操作,但需要注意的是,Docker 镜像本身设计用来包含应用程序和其依赖的环境,而不是用来包含数据。数据通常应该通过卷(Volumes)或绑定挂载(Bind Mounts)来管理,以保持容器的无状态性。这样做的好处是可以保证容器的可移植性和灵活性。
然而,如果确实需要将数据一起与镜像打包,比如在某些特定的情况下(例如,为了方便快速部署或测试),可以通过在构建镜像时将数据复制到镜像中来实现。这里是推送包含数据的 Docker 镜像到 Docker Hub 的步骤:
1.1 准备 Dockerfile
需要一个 Dockerfile 来定义如何构建包含数据的 Docker 镜像。例如:
# 使用官方的 MySQL 镜像作为基础镜像
FROM mysql:5.7
# 将数据目录复制到镜像中
COPY ./data /var/lib/mysql/data
1.2 构建镜像
使用下面的命令在包含 Dockerfile 的目录中构建新的 Docker 镜像:
docker build -t yourusername/myimage:tag
这里,yourusername/myimage:tag 应该替换为希望用来在 Docker Hub 上标识您的镜像的用户名、镜像名称和标签。例如,如果 Docker Hub 用户名是 john_doe,可能想要将镜像命名为 mysql_with_data,并给这个特定构建添加一个标签如 latest:
docker build -t john_doe/mysql_with_data:latest .
1.3 登录到 Docker Hub
在推送镜像之前,需要使用 Docker Hub 凭据登录:
docker login
1.4 推送镜像到 Docker Hub
现在可以将构建好的镜像推送到 Docker Hub:
docker push john_doe/mysql_with_data:latest
这条命令会将镜像上传到 Docker Hub,使得其他人或其他系统可以下载和使用你的镜像。
1.5 验证镜像
完成推送后,可以在 Docker Hub 的网站上查看镜像,确保它已经正确上传。
1.6 注意事项
- 数据持久性与安全性:将数据打包进 Docker 镜像并不是管理数据的最佳实践,尤其是对于生产环境。这种做法可能会导致数据安全问题,且不利于数据的更新和管理。建议只在特定的情况下,如测试、演示或非常特定的部署需求中使用。
- 镜像大小:将数据包含在镜像中可能会显著增加镜像的大小,这会影响推送和拉取镜像的时间,同时也会增加存储成本。
- 数据更新:如果数据有更新,需要重新构建和推送整个镜像。这可能会导致版本控制和回滚操作复杂化。
二. 具体案例
如我要将我服务器上的3个容器和数据,定时上传到 Docker Hub 中作为备份的话,要怎么做呢?
这里容器分别是 nginx、mysql、wordpress,对原有 Docker Hub 上的镜像重新打标记,后缀 latest 改为 当前日期,并上传最新的镜像。
2.1 目录结构
├── log
│ └── wordpress
│ └── logfile_20240424.log
├── upload_worpress_images.sh
└── wordpress
├── wp_mysql
│ ├── Dockerfile
│ └── run_script.sh
├── wp_nginx
│ ├── Dockerfile
│ └── run_script.sh
└── wp_wordpress
├── Dockerfile
└── run_script.sh
其中,log 是记录定时日志的目录;
upload_worpress_images.sh 是上传镜像文件到 Docker Hub 的脚本;
wordpress 是存储对应容器数据、Dockerfile 和生成镜像脚本的目录。
2.2 脚本参考
2.2.1 upload_worpress_images.sh
#!/bin/bash
# 配置变量
USERNAME="bluebro"
REPOSITORY="blue_repository"
DATE_TAG=$(date +%Y%m%d)
# 定义要处理的容器和对应的镜像名
declare -A containers
containers=(["wp_nginx"]="wp_nginx" ["wp_mysql"]="wp_mysql" ["wp_wordpress"]="wp_wordpress")
# containers=(["wp_mysql"]="wp_mysql")
# 登录 Docker Hub
echo "===> Logging into Docker Hub..."
docker login # 确保事先配置好了 Docker 的认证信息,或在这里提供用户名和密码
# 循环遍历容器,处理镜像
for container in "${!containers[@]}"; do
image_base="$USERNAME/$REPOSITORY:${containers[$container]}"
image_now="${image_base}-now"
image_latest="${image_base}-latest"
image_date_tag="${image_base}-$DATE_TAG"
echo "===> Processing container: $container..."
# 获取本地 now 镜像ID
now_image_id=$(docker images -q $image_now)
# 检查是否获取到本地 now 镜像ID, 有则删除
if [ ! -z "$now_image_id" ]; then
echo "===> Removing local image: $image_now"
echo "===> docker rmi $image_now"
docker rmi $image_now
else
echo "===> No local image to remove: $image_now"
fi
#
# 获取本地 latest 镜像ID
latest_image_id=$(docker images -q $image_latest)
# 检查是否获取到本地 latest 镜像ID, 有则删除
if [ ! -z "$latest_image_id" ]; then
echo "===> Removing local image: $image_latest"
echo "===> docker rmi $image_latest"
docker rmi $image_latest
else
echo "===> No local image to remove: $image_latest"
fi
# 从 Docker Hub 拉取最新的镜像,重新标记 tag 并上传到
echo "===> docker pull $image_latest"
if docker pull $image_latest; then
echo "===> Retagging $image_latest to $image_date_tag..."
echo "===> docker tag $image_latest $image_date_tag"
docker tag $image_latest $image_date_tag
echo "===> docker push $image_date_tag"
docker push $image_date_tag
echo "===> docker rmi $image_latest $image_date_tag"
docker rmi $image_latest $image_date_tag # 清理拉取和重标记的镜像
fi
# 提交容器为最新镜像并推送
echo "===> Committing container $container to $image_latest"
# 构建基础镜像
echo "===> docker commit $container $image_now"
docker commit $container $image_now
# 调用自定义生成的镜像脚本
echo "===> sh /opt/cmd/wordpress/$container/run_script.sh"
sh /opt/cmd/wordpress/$container/run_script.sh
# 将镜像推送到 docker hub
echo "===> docker push $image_latest"
docker push $image_latest
done
echo "===> Images processing complete."
2.2.2 wp_mysql
2.2.2.1 Dockerfile
# 使用 mysql 的基础镜像
FROM bluebro/blue_repository:wp_mysql-now
# 将你的数据库数据复制到镜像中
# 一定是Mysql数据卷的路径!!!
COPY mysql_data/wp_mysql/ /var/lib/mysql
2.2.2.2 run_script.sh
#!/bin/bash
DIR='/opt/cmd/wordpress/wp_mysql'
mkdir -p $DIR
# 进入目标目录
echo "===> cd $DIR"
cd $DIR
# 检查目录是否存在,如果存在则删除
if [ -d "mysql_data" ]; then
echo "===> mysql_data directory exists. Removing..."
echo "===> rm -rf ./mysql_data"
rm -rf ./mysql_data
fi
# 创建新的目录
echo "===> mkdir mysql_data"
mkdir mysql_data
# 将原始挂载卷文件复制到当前目录下
echo "===> cp -r /data/wordpress/wp_mysql ./mysql_data"
cp -r /data/wordpress/wp_mysql/ ./mysql_data
# 通过 Dockerfile 构建新镜像
echo "===> docker build -t bluebro/blue_repository:wp_mysql-latest ."
docker build -t bluebro/blue_repository:wp_mysql-latest .
2.2.3 wp_nginx
2.2.3.1 Dockerfile
# 使用 nginx 的基础镜像
FROM bluebro/blue_repository:wp_nginx-now
# 将你的数据复制到镜像中
# 一定是 nginx 数据卷的路径!!!
COPY nginx_data/wp_nginx/confs/nginx.conf /etc/nginx/nginx.conf
COPY nginx_data/wp_nginx/htmls/ /usr/share/nginx/html
COPY nginx_data/wp_nginx/logs/ /var/log/nginx
COPY nginx_data/wp_nginx/certs/ /etc/nginx/certs
2.2.3.2 run_script.sh
#!/bin/bash
DIR='/opt/cmd/wordpress/wp_nginx'
mkdir -p $DIR
# 进入目标目录
echo "===> cd $DIR"
cd $DIR
# 检查目录是否存在,如果存在则删除
if [ -d "nginx_data" ]; then
echo "===> nginx_data directory exists. Removing..."
echo "===> rm -rf ./nginx_data"
rm -rf ./nginx_data
fi
# 创建新的目录
echo "===> mkdir nginx_data"
mkdir nginx_data
# 将原始挂载卷文件复制到当前目录下
echo "===> cp -r /data/wordpress/wp_nginx ./nginx_data"
cp -r /data/wordpress/wp_nginx/ ./nginx_data
# 通过 Dockerfile 构建新镜像
echo "===> docker build -t bluebro/blue_repository:wp_nginx-latest ."
docker build -t bluebro/blue_repository:wp_nginx-latest .
2.2.4 wp_wordpress
2.2.4.1 Dockerfile
# 使用 wordpress 的基础镜像
FROM bluebro/blue_repository:wp_wordpress-now
# 将你的数据复制到镜像中
# 一定是 wordpress 数据文件的路径!!!
COPY wordpress_data/wp_wordpress/ /var/www/html
2.2.4.2 run_script.sh
#!/bin/bash
DIR='/opt/cmd/wordpress/wp_wordpress'
mkdir -p $DIR
# 进入目标目录
echo "===> cd $DIR"
cd $DIR
# 检查目录是否存在,如果存在则删除
if [ -d "wordpress_data" ]; then
echo "===> wordpress_data directory exists. Removing..."
echo "===> rm -rf ./wordpress_data"
rm -rf ./wordpress_data
fi
# 创建新的目录
echo "===> mkdir wordpress_data"
mkdir wordpress_data
# 将原始挂载卷文件复制到当前目录下
echo "===> cp -r /data/wordpress/wp_wordpress ./wordpress_data"
cp -r /data/wordpress/wp_wordpress/ ./wordpress_data
# 通过 Dockerfile 构建新镜像
echo "===> docker build -t bluebro/blue_repository:wp_wordpress-latest ."
docker build -t bluebro/blue_repository:wp_wordpress-latest .
2.3 验证 Docker Hub
三. 使用 crontab 定时任务脚本
这里不过多介绍用法。
0 1 * * 1 bash /opt/cmd/upload_worpress_images.sh \
> /opt/cmd/log/wordpress/logfile_$(date "+\%Y\%m\%d").log 2>&1
Comments | NOTHING