一键部署脚本(MySQL + Redis)

举报
yd_272031863 发表于 2026/11/05 23:42:46 2026/11/05
【摘要】 依赖服务一键部署脚本(MySQL + Redis)本文档为「拾壹博客项目部署方案」系列文档之一,提供 MySQL 8.0 与 Redis 7 的 Docker 一键部署脚本及使用说明。脚本基于 02-依赖服务部署.md 增强,已内置生产环境关键配置与常见坑处理。 1. 脚本文件脚本部署内容镜像deploy-mysql.shMySQL 8.0 数据库mysql:8.0.36(固定版本)dep...

依赖服务一键部署脚本(MySQL + Redis)

本文档为「拾壹博客项目部署方案」系列文档之一,提供 MySQL 8.0 与 Redis 7 的 Docker 一键部署脚本及使用说明。脚本基于 02-依赖服务部署.md 增强,已内置生产环境关键配置与常见坑处理。


1. 脚本文件

脚本 部署内容 镜像
deploy-mysql.sh MySQL 8.0 数据库 mysql:8.0.36(固定版本)
deploy-redis.sh Redis 7 缓存 redis:7.2.4-alpine(固定版本)

2. 前置条件

执行本脚本前,需已完成:

  1. 系统 yum 源配置(CentOS Stream 9 无需切换 vault 源)
  2. Docker CE 安装与启动(见 01-基础环境安装.md)
  3. Docker 守护进程配置完成(daemon.json 镜像加速器等)

验证 Docker 已就绪:

docker info | grep "Server Version"

3. 使用步骤

3.1 上传脚本到服务器

将两个 .sh 文件上传到服务器任意目录(建议 /opt/deploy/):

mkdir -p /opt/deploy
# 通过 scp / sftp / rz 等方式上传 deploy-mysql.sh、deploy-redis.sh 到 /opt/deploy/

3.2 确认服务器内存并调整参数

free -h

根据总内存编辑脚本顶部参数:

服务器内存 deploy-mysql.sh deploy-redis.sh
2 GB INNODB_BUFFER_POOL_SIZE='512M' MAXMEMORY='256mb'
4 GB INNODB_BUFFER_POOL_SIZE='1G'(默认) MAXMEMORY='512mb'(默认)
8 GB+ INNODB_BUFFER_POOL_SIZE='2G' MAXMEMORY='1gb'

3.3 赋予执行权限

chmod +x /opt/deploy/deploy-mysql.sh /opt/deploy/deploy-redis.sh

3.4 执行部署

# 先部署 MySQL(首次拉取镜像 + 初始化约 1~2 分钟)
/opt/deploy/deploy-mysql.sh

# 再部署 Redis(约 10 秒)
/opt/deploy/deploy-redis.sh

脚本会自动:创建目录 → 写入配置文件 → 启动容器 → 等待就绪 → 验证关键配置 → 输出部署结果。

3.5 验证部署结果

脚本执行末尾会输出验证信息。也可手动复查:

# 容器状态
docker ps | grep -E 'my-mysql|my-redis'

# MySQL 关键配置
docker exec my-mysql mysql -uroot -p'Mysql@Pr0d#2026!' -e \
  "SHOW VARIABLES LIKE 'lower_case_table_names'; SHOW VARIABLES LIKE 'time_zone';"

# Redis 连通性
docker exec my-redis redis-cli -a 'R3dis@Pr0d#2026!' ping

4. 脚本内置的关键处理

项 原文档 本脚本 说明
表名大小写 区分(Linux 默认) lower_case_table_names=1 不区分大小写,与 Windows/IDE 一致
时区 UTC(NOW() 偏 8 小时) default-time-zone='+8:00' + TZ=Asia/Shanghai 避免时间字段偏移
SELinux 挂载 无 :z 标签 所有 -v 加 :z CentOS Stream 9 默认 SELinux enforcing,不加会启动失败
端口暴露 0.0.0.0(公网直连) 默认 127.0.0.1 仅本机访问,后端同机最安全
镜像版本 mysql:8.0 / redis:7-alpine(滚动 tag) 固定 8.0.36 / 7.2.4-alpine 避免未来小版本升级引入 bug
慢日志目录权限 未处理 chmod 777 日志目录 防止容器内 mysql 用户无法写慢查询日志
就绪检测 固定 sleep 30 mysqladmin ping 轮询最多 120 秒 避免初始化慢时验证失败
重复部署保护 无 检查同名容器 + 数据目录非空 防止误操作覆盖已有数据
Redis 验证命令 用已禁用的 CONFIG GET 改用 INFO memory CONFIG 已被 rename-command 禁用

5. 可配置参数说明

5.1 deploy-mysql .sh

参数 默认值 说明
MYSQL_ROOT_PASSWORD Mysql@Pr0d#2026! root 密码,生产环境务必修改
MYSQL_DATABASE blog 容器启动时自动创建的数据库
MYSQL_PORT 3306 宿主机映射端口
BIND_ADDR 127.0.0.1 绑定地址:127.0.0.1 仅本机 / 0.0.0.0 所有网卡
IMAGE mysql:8.0.36 镜像版本,固定避免滚动升级
INNODB_BUFFER_POOL_SIZE 1G InnoDB 缓冲池,建议物理内存的 50%~70%
CONTAINER_NAME my-mysql 容器名称

5.2 deploy-redis .sh

参数 默认值 说明
REDIS_PASSWORD R3dis@Pr0d#2026! Redis 密码,生产环境务必修改
REDIS_PORT 6379 宿主机映射端口
BIND_ADDR 127.0.0.1 绑定地址:127.0.0.1 仅本机 / 0.0.0.0 所有网卡
IMAGE redis:7.2.4-alpine 镜像版本,固定
MAXMEMORY 512mb Redis 最大内存,达到上限按 LRU 淘汰
CONTAINER_NAME my-redis 容器名称

6. 日常管理命令

# 查看运行状态
docker ps | grep -E 'my-mysql|my-redis'

# 查看实时日志
docker logs -f --tail=100 my-mysql
docker logs -f --tail=100 my-redis

# 进入 MySQL 命令行
docker exec -it my-mysql mysql -uroot -p'Mysql@Pr0d#2026!'

# 进入 Redis 命令行
docker exec -it my-redis redis-cli -a 'R3dis@Pr0d#2026!'

# 重启服务
docker restart my-mysql
docker restart my-redis

# 查看资源占用
docker stats my-mysql my-redis

7. 重新部署与卸载

7.1 重新部署 MySQL(清空数据,慎用)

docker rm -f my-mysql
rm -rf /opt/my-app/services/data/mysql/*
/opt/deploy/deploy-mysql.sh

警告:rm -rf 会清空所有数据库数据,仅全新部署或确认数据可丢弃时使用。

7.2 重新部署 Redis(清空数据)

docker rm -f my-redis
rm -rf /opt/my-app/services/data/redis/*
/opt/deploy/deploy-redis.sh

7.3 仅重启使配置生效(不清数据)

修改 my.cnf 或 redis.conf 后:

docker restart my-mysql
docker restart my-redis

8. 常见问题

8.1 MySQL 启动失败:lower_case_table_names 冲突

现象:日志报 Different lower_case_table_names settings for server ('1') and data dictionary ('0')

原因:数据目录已用旧参数初始化过,MySQL 8.0 不允许初始化后修改此参数。

解决:清空数据目录重新初始化(仅全新部署可用):

docker rm -f my-mysql
rm -rf /opt/my-app/services/data/mysql/*
/opt/deploy/deploy-mysql.sh

8.2 MySQL 启动失败:SELinux 权限拒绝

现象:日志报 Permission denied 或容器反复重启

原因:SELinux 阻止容器访问挂载目录

解决:脚本已为所有挂载加 :z 标签。若仍失败,确认 SELinux 状态:

getenforce
# 若输出 Enforcing 且仍失败,临时排查可:
setenforce 0
docker restart my-mysql
# (生产环境不建议关闭 SELinux,应排查 :z 标签是否生效)

8.3 老客户端连接 MySQL 报认证插件错误

现象:Authentication plugin 'caching_sha2_password' cannot be loaded

原因:MySQL 8.0 默认使用 caching_sha2_password,老版本客户端(MySQL Connector/J 5.x、老 Navicat)不支持

解决:改 root 认证方式为 mysql_native_password:

docker exec my-mysql mysql -uroot -p'Mysql@Pr0d#2026!' -e \
  "ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'Mysql@Pr0d#2026!';"

拾壹博客后端若使用 MySQL Connector/J 8.x 则无需此操作。

8.4 Redis 连接报 NOAUTH

现象:NOAUTH Authentication required

原因:未提供密码或密码错误

解决:连接时必须带 -a 参数:

docker exec -it my-redis redis-cli -a 'R3dis@Pr0d#2026!' ping

8.5 后端无法连接 MySQL/Redis

排查步骤:

  1. 确认后端与 MySQL/Redis 是否在同一台机器
    • 同机:BIND_ADDR=127.0.0.1 即可,后端用 127.0.0.1 连接
    • 跨机:需改 BIND_ADDR=0.0.0.0 并配置 firewalld 限制来源 IP
  2. 确认端口是否放通:
# 跨机访问时,放通指定来源 IP
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=后端IP port port=3306 protocol=tcp accept'
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=后端IP port port=6379 protocol=tcp accept'
firewall-cmd --reload
  1. 确认后端配置文件中的密码与脚本一致

9. 部署前确认事项

执行脚本前,请确认以下两点:

9.1 后端部署位置

场景 BIND_ADDR 设置 说明
后端与 MySQL/Redis 同机 127.0.0.1(默认) 最安全,仅本机访问
后端在其他机器 0.0.0.0 需配合 firewalld 限制来源 IP,禁止公网裸连

9.2 密码修改

生产环境强烈建议修改默认密码:

  • deploy-mysql.sh 顶部 MYSQL_ROOT_PASSWORD
  • deploy-redis.sh 顶部 REDIS_PASSWORD

修改后,后端 application-prod.yml 中的对应密码需同步修改:

spring:
  datasource:
    password: 新MySQL密码
  redis:
    password: 新Redis密码

10. 部署后的目录结构

/opt/my-app/services/
├─ data/
│  ├─ mysql/          # MySQL 数据文件
│  └─ redis/          # Redis 持久化文件(dump.rdb + appendonly.aof)
├─ config/
│  ├─ mysql/my.cnf    # MySQL 配置
│  └─ redis/redis.conf # Redis 配置
├─ logs/
│  └─ mysql/          # MySQL 慢查询日志
└─ backup/
   └─ mysql/          # MySQL 备份(需另配备份脚本,见 02-依赖服务部署.md 1.5 节)

附件


1、deploy-mysql .sh


#!/bin/bash
#=============================================================
# MySQL 8.0 Docker 一键部署脚本
# 适用:CentOS Stream 9 / CentOS 8(已完成 yum + docker 安装)
#=============================================================

# ---------- 可配置参数(按需修改)----------
MYSQL_ROOT_PASSWORD='Mysql@Pr0d#2026!'   # root 密码,生产务必修改
MYSQL_DATABASE='blog'                     # 自动创建的数据库
MYSQL_PORT=3306                           # 宿主机端口
BIND_ADDR='127.0.0.1'                     # 127.0.0.1=仅本机访问 / 0.0.0.0=所有网卡(需配防火墙)
IMAGE='mysql:8.0.36'                      # 镜像版本(固定,避免滚动升级引入风险)
INNODB_BUFFER_POOL_SIZE='512M'              # InnoDB缓冲池:2G机=512M / 4G=1G / 8G+=2G
CONTAINER_NAME='my-mysql'
# ------------------------------------------

BASE='/opt/my-app/services'
DATA_DIR="$BASE/data/mysql"
CONF_DIR="$BASE/config/mysql"
LOG_DIR="$BASE/logs/mysql"

echo ">>> MySQL 部署脚本开始"

# 1. 检查 docker
if ! command -v docker >/dev/null 2>&1; then
  echo "[FAIL] 未安装 docker,请先执行 01-基础环境安装.md"
  exit 1
fi

# 2. 检查同名容器
if docker ps -a --format '{{.Names}}' | grep -qx "$CONTAINER_NAME"; then
  echo "[FAIL] 容器 $CONTAINER_NAME 已存在。"
  echo "       重新部署请先执行:docker rm -f $CONTAINER_NAME"
  exit 1
fi

# 3. 检查数据目录是否非空(避免 lower_case_table_names 冲突)
if [ -d "$DATA_DIR" ] && [ -n "$(ls -A "$DATA_DIR" 2>/dev/null)" ]; then
  echo "[FAIL] 数据目录 $DATA_DIR 非空。"
  echo "       若为旧数据(且 lower_case_table_names 曾为 0),需清空重来:"
  echo "       rm -rf $DATA_DIR/*"
  echo "       (会清空所有数据,仅全新部署可用)"
  exit 1
fi

# 4. 创建目录
echo ">>> 创建目录..."
mkdir -p "$DATA_DIR" "$CONF_DIR" "$LOG_DIR"

# 5. 写 my.cnf
echo ">>> 写入 my.cnf..."
cat > "$CONF_DIR/my.cnf" <<EOF
[mysqld]
# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'

# 表名不区分大小写(必须在数据目录首次初始化前设置,8.0 初始化后不可改)
lower_case_table_names = 1

# 时区(容器默认 UTC,改为东八区,避免 NOW() 偏 8 小时)
default-time-zone = '+8:00'

# 连接配置
max_connections = 500
max_connect_errors = 100
wait_timeout = 28800
interactive_timeout = 28800

# InnoDB 缓冲池(根据服务器内存调整)
innodb_buffer_pool_size = $INNODB_BUFFER_POOL_SIZE
innodb_log_buffer_size = 16M
innodb_log_file_size = 256M

# 慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

# 二进制日志(数据恢复 + 主从复制)
log_bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
max_binlog_size = 100M

# 安全
local_infile = 0
skip_name_resolve = 1

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4
EOF

# 6. 日志目录权限(容器内 mysql 用户需可写慢查询日志)
chmod 777 "$LOG_DIR"

# 7. 启动容器
echo ">>> 启动 MySQL 容器(镜像 $IMAGE,首次会自动拉取)..."
docker run -d \
  --name "$CONTAINER_NAME" \
  -p ${BIND_ADDR}:${MYSQL_PORT}:3306 \
  -e MYSQL_ROOT_PASSWORD="$MYSQL_ROOT_PASSWORD" \
  -e MYSQL_DATABASE="$MYSQL_DATABASE" \
  -e MYSQL_CHARACTER_SET_SERVER=utf8mb4 \
  -e MYSQL_COLLATION_SERVER=utf8mb4_unicode_ci \
  -e TZ=Asia/Shanghai \
  -v ${DATA_DIR}:/var/lib/mysql:z \
  -v ${CONF_DIR}/my.cnf:/etc/mysql/conf.d/my.cnf:z \
  -v ${LOG_DIR}:/var/log/mysql:z \
  --restart=always \
  "$IMAGE"

# 8. 等待就绪
echo ">>> 等待 MySQL 初始化就绪(最多 120 秒)..."
READY=0
for i in $(seq 1 60); do
  if docker exec "$CONTAINER_NAME" mysqladmin ping -uroot -p"$MYSQL_ROOT_PASSWORD" --silent 2>/dev/null; then
    READY=1
    break
  fi
  sleep 2
done

if [ "$READY" -ne 1 ]; then
  echo "[FAIL] MySQL 未就绪,最近日志:"
  docker logs --tail=50 "$CONTAINER_NAME"
  exit 1
fi

echo "[OK] MySQL 已就绪"

# 9. 验证关键配置
echo ">>> 验证配置..."
docker exec "$CONTAINER_NAME" mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e \
  "SHOW VARIABLES LIKE 'lower_case_table_names'; \
   SHOW VARIABLES LIKE 'character_set_server'; \
   SHOW VARIABLES LIKE 'time_zone'; \
   SHOW VARIABLES LIKE 'max_connections';" 2>/dev/null

# 10. 完成
echo ""
echo "=================================================="
echo "[OK] MySQL 部署完成"
echo "  容器名   : $CONTAINER_NAME"
echo "  镜像     : $IMAGE"
echo "  端口     : ${BIND_ADDR}:${MYSQL_PORT} -> 3306"
echo "  数据目录 : $DATA_DIR"
echo "  配置文件 : $CONF_DIR/my.cnf"
echo "  日志目录 : $LOG_DIR"
echo "  连接命令 : mysql -h127.0.0.1 -P$MYSQL_PORT -uroot -p'$MYSQL_ROOT_PASSWORD'"
echo "=================================================="

2、deploy-redis .sh


#!/bin/bash
#=============================================================
# Redis 7 Docker 一键部署脚本
# 适用:CentOS Stream 9 / CentOS 8(已完成 yum + docker 安装)
#=============================================================

# ---------- 可配置参数(按需修改)----------
REDIS_PASSWORD='R3dis@Pr0d#2026!'         # 密码,生产务必修改
REDIS_PORT=6379
BIND_ADDR='127.0.0.1'                     # 127.0.0.1=仅本机 / 0.0.0.0=所有网卡(必须配防火墙+强密码)
IMAGE='redis:7.2.4-alpine'                # 镜像版本(固定)
MAXMEMORY='256mb'                         # 最大内存:2G机=256mb / 4G=512mb / 8G+=1gb
CONTAINER_NAME='my-redis'
# ------------------------------------------

BASE='/opt/my-app/services'
DATA_DIR="$BASE/data/redis"
CONF_DIR="$BASE/config/redis"

echo ">>> Redis 部署脚本开始"

# 1. 检查 docker
if ! command -v docker >/dev/null 2>&1; then
  echo "[FAIL] 未安装 docker,请先执行 01-基础环境安装.md"
  exit 1
fi

# 2. 检查同名容器
if docker ps -a --format '{{.Names}}' | grep -qx "$CONTAINER_NAME"; then
  echo "[FAIL] 容器 $CONTAINER_NAME 已存在。"
  echo "       重新部署请先执行:docker rm -f $CONTAINER_NAME"
  exit 1
fi

# 3. 创建目录
echo ">>> 创建目录..."
mkdir -p "$DATA_DIR" "$CONF_DIR"

# 4. 写 redis.conf
echo ">>> 写入 redis.conf..."
cat > "$CONF_DIR/redis.conf" <<EOF
# 容器内绑定(必须 0.0.0.0 才能被端口映射访问;宿主机暴露由 docker -p 控制)
bind 0.0.0.0
port 6379

# 密码认证
requirepass $REDIS_PASSWORD

# 内存限制(达到上限按 LRU 淘汰,适合缓存场景)
maxmemory $MAXMEMORY
maxmemory-policy allkeys-lru

# RDB 持久化
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /data

# AOF 持久化(每秒同步,兼顾性能与安全)
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no

# 禁用危险命令
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command DEBUG ""

# 其他
loglevel notice
maxclients 10000
timeout 300
tcp-keepalive 60
EOF

# 5. 启动容器
echo ">>> 启动 Redis 容器(镜像 $IMAGE,首次会自动拉取)..."
docker run -d \
  --name "$CONTAINER_NAME" \
  -p ${BIND_ADDR}:${REDIS_PORT}:6379 \
  -v ${DATA_DIR}:/data:z \
  -v ${CONF_DIR}/redis.conf:/usr/local/etc/redis/redis.conf:z \
  --restart=always \
  "$IMAGE" redis-server /usr/local/etc/redis/redis.conf

# 6. 等待就绪
echo ">>> 等待 Redis 就绪..."
sleep 3
if ! docker ps --format '{{.Names}}' | grep -qx "$CONTAINER_NAME"; then
  echo "[FAIL] Redis 容器未运行,最近日志:"
  docker logs --tail=50 "$CONTAINER_NAME"
  exit 1
fi

# 7. 验证
echo ">>> 验证..."
docker exec "$CONTAINER_NAME" redis-cli -a "$REDIS_PASSWORD" ping 2>/dev/null
docker exec "$CONTAINER_NAME" redis-cli -a "$REDIS_PASSWORD" INFO memory 2>/dev/null | grep -E "maxmemory:|used_memory_human:|maxmemory_policy:"

# 8. 完成
echo ""
echo "=================================================="
echo "[OK] Redis 部署完成"
echo "  容器名   : $CONTAINER_NAME"
echo "  镜像     : $IMAGE"
echo "  端口     : ${BIND_ADDR}:${REDIS_PORT} -> 6379"
echo "  数据目录 : $DATA_DIR"
echo "  配置文件 : $CONF_DIR/redis.conf"
echo "  连接命令 : redis-cli -h127.0.0.1 -p$REDIS_PORT -a '$REDIS_PASSWORD'"
echo "=================================================="
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。