本文目录导读:

在Shell脚本中配置容器持久化存储,主要涉及Docker卷(Volume)、绑定挂载(Bind Mount)和临时挂载(tmpfs)三种方式,以下是通过Shell脚本实现持久化存储的常见方法:
使用Docker卷(Volume)
#!/bin/bash # 创建卷 docker volume create myapp-data # 运行容器并挂载卷 docker run -d \ --name myapp \ -v myapp-data:/app/data \ nginx:latest
带条件的卷操作
#!/bin/bash
VOLUME_NAME="postgres-data"
# 检查卷是否存在,不存在则创建
if ! docker volume inspect $VOLUME_NAME > /dev/null 2>&1; then
echo "创建卷: $VOLUME_NAME"
docker volume create $VOLUME_NAME
fi
# 运行PostgreSQL使用持久化卷
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=mysecretpassword \
-v $VOLUME_NAME:/var/lib/postgresql/data \
postgres:13
使用绑定挂载(Bind Mount)
#!/bin/bash # 定义宿主机路径 HOST_DATA_DIR="/opt/data/myapp" CONTAINER_DATA_DIR="/app/data" # 确保宿主机目录存在 mkdir -p $HOST_DATA_DIR # 运行容器并绑定挂载 docker run -d \ --name myapp \ -v $HOST_DATA_DIR:$CONTAINER_DATA_DIR \ nginx:latest
带权限设置的绑定挂载
#!/bin/bash DATA_DIR="/var/data/mysql" MYSQL_USER_ID=999 # MySQL默认用户ID # 创建目录并设置权限 mkdir -p $DATA_DIR chown -R $MYSQL_USER_ID:$MYSQL_USER_ID $DATA_DIR chmod 755 $DATA_DIR # 运行MySQL容器 docker run -d \ --name mysql \ -e MYSQL_ROOT_PASSWORD=rootpassword \ -v $DATA_DIR:/var/lib/mysql \ mysql:8.0
使用Docker Compose(脚本驱动)
#!/bin/bash
cat > docker-compose.yml <<EOF
version: '3.8'
services:
app:
image: nginx:latest
volumes:
- app-data:/app/data
- ./config:/etc/nginx/conf.d
ports:
- "8080:80"
volumes:
app-data:
EOF
# 启动服务
docker-compose up -d
高级脚本:多容器共享卷
#!/bin/bash
# 函数:创建或复用卷
create_or_use_volume() {
local vol_name=$1
if docker volume ls -q | grep -q "^${vol_name}$"; then
echo "使用现有卷: $vol_name"
else
echo "创建新卷: $vol_name"
docker volume create $vol_name
fi
}
# 创建共享卷
SHARED_VOL="shared-data"
create_or_use_volume $SHARED_VOL
# 启动多个容器共享同一卷
docker run -d --name app1 -v $SHARED_VOL:/data alpine sleep infinity
docker run -d --name app2 -v $SHARED_VOL:/data alpine sleep infinity
# 从app1写入数据,app2可以读取
docker exec app1 sh -c "echo '共享数据' > /data/test.txt"
docker exec app2 cat /data/test.txt
# 清理
docker rm -f app1 app2
docker volume rm $SHARED_VOL
生产环境完整示例
#!/bin/bash
# 配置持久化存储的完整Shell脚本
set -euo pipefail
# 配置变量
APP_NAME="webapp"
VOLUME_NAME="${APP_NAME}-data"
BACKUP_DIR="/data/backups"
MOUNT_POINT="/app/data"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 创建或验证卷
setup_volume() {
if docker volume inspect $VOLUME_NAME > /dev/null 2>&1; then
log "卷 $VOLUME_NAME 已存在"
else
log "创建卷 $VOLUME_NAME"
docker volume create \
--label app=$APP_NAME \
--label environment=production \
$VOLUME_NAME
fi
}
# 备份卷数据
backup_volume() {
mkdir -p $BACKUP_DIR
local backup_file="$BACKUP_DIR/${VOLUME_NAME}_$(date +%Y%m%d_%H%M%S).tar.gz"
log "备份卷数据到 $backup_file"
docker run --rm \
-v $VOLUME_NAME:/source \
-v $BACKUP_DIR:/backup \
alpine \
tar czf /backup/$(basename $backup_file) -C /source .
}
# 运行容器
run_container() {
log "启动容器 $APP_NAME"
docker run -d \
--name $APP_NAME \
-v $VOLUME_NAME:$MOUNT_POINT \
--restart unless-stopped \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx:alpine
}
# 主函数
main() {
# 执行备份(可选)
if [ "${1:-}" = "--with-backup" ]; then
backup_volume
fi
setup_volume
run_container
log "容器 $APP_NAME 已启动,数据卷: $VOLUME_NAME"
log "挂载点: $MOUNT_POINT"
}
# 执行主函数
main "$@"
不同存储类型的区别
| 特性 | Docker卷 | 绑定挂载 | tmpfs |
|---|---|---|---|
| 数据持久性 | 持久(生命周期独立) | 持久(依赖宿主机目录) | 临时(容器停止即消失) |
| 性能 | 较好 | 最好(直接文件系统) | 极快(内存中) |
| 备份恢复 | 容易(专用命令) | 常规文件备份 | 不需要 |
| 跨主机迁移 | 支持(需要卷驱动) | 不支持(依赖路径) | 不支持 |
| 权限控制 | Docker管理 | 手动管理 | 自动 |
最佳实践总结
#!/bin/bash # 1. 始终使用命名卷,避免匿名卷 docker volume create myapp-data # 2. 绑定挂载时设置正确的权限 chown -R 1000:1000 /host/data # 3. 使用read-only提高安全性 -v /host/config:/app/config:ro # 4. 定期备份 docker run --rm -v myapp-data:/data alpine tar czf /backup/data.tar.gz /data # 5. 清理未使用的卷 docker volume prune -f # 6. 生产环境使用专用存储驱动 docker run -d --volume-driver=rexray -v myapp-data:/data nginx
这些Shell脚本可以根据你的具体需求调整,适应不同的持久化存储场景,生产环境中建议结合监控和备份策略使用。