一键部署脚本(MySQL + Redis)
依赖服务一键部署脚本(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. 前置条件
执行本脚本前,需已完成:
- 系统 yum 源配置(CentOS Stream 9 无需切换 vault 源)
- Docker CE 安装与启动(见
01-基础环境安装.md) - 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
排查步骤:
- 确认后端与 MySQL/Redis 是否在同一台机器
- 同机:
BIND_ADDR=127.0.0.1即可,后端用127.0.0.1连接 - 跨机:需改
BIND_ADDR=0.0.0.0并配置 firewalld 限制来源 IP
- 同机:
- 确认端口是否放通:
# 跨机访问时,放通指定来源 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
- 确认后端配置文件中的密码与脚本一致
9. 部署前确认事项
执行脚本前,请确认以下两点:
9.1 后端部署位置
| 场景 | BIND_ADDR 设置 |
说明 |
|---|---|---|
| 后端与 MySQL/Redis 同机 | 127.0.0.1(默认) |
最安全,仅本机访问 |
| 后端在其他机器 | 0.0.0.0 |
需配合 firewalld 限制来源 IP,禁止公网裸连 |
9.2 密码修改
生产环境强烈建议修改默认密码:
deploy-mysql.sh顶部MYSQL_ROOT_PASSWORDdeploy-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 "=================================================="
- 点赞
- 收藏
- 关注作者
评论(0)