Docker Compose 部署 MySQL 中文乱码避坑指南

Docker Compose 部署 MySQL 中文乱码避坑指南

基于 RuoYi-Vue + MySQL 8.0 Docker 部署踩坑实录

问题现象

使用 Docker Compose 部署若依后台管理系统时,遇到以下中文乱码问题:

  1. Navicat 查询中文乱码 :数据库表中的中文字段显示为乱码(如 若依ç§'技
  2. 系统菜单接口返回乱码:前端页面菜单名称、部门名称等中文内容显示异常
  3. 后端日志中的中文也是乱码

根本原因

MySQL 官方 Docker 镜像在执行 /docker-entrypoint-initdb.d/*.sql 初始化脚本时,默认使用 latin1 客户端字符集,导致 UTF-8 编码的 SQL 文件被错误解析。

即使你在 docker-compose.yml 中配置了:

yaml 复制代码
command: >
  --character-set-server=utf8mb4
  --collation-server=utf8mb4_unicode_ci

这些参数只影响 MySQL Server 运行时的字符集 ,不影响 entrypoint 执行初始化脚本时的客户端字符集

踩坑过程

坑 1:以为配置了 server 字符集就万事大吉

yaml 复制代码
# 错误示范 ❌
command: >
  --character-set-server=utf8mb4
  --collation-server=utf8mb4_unicode_ci

结果:

  • SHOW VARIABLES LIKE 'character_set_server';utf8mb4
  • 但初始化后的数据仍然是乱码 ❌

坑 2:SQL 文件开头加 SET NAMES utf8mb4

sql 复制代码
-- 无效 ❌
SET NAMES utf8mb4;
SET CHARACTER SET utf8mb4;

结果:entrypoint 执行 SQL 时,第一个连接就已经是 latin1,SET NAMES 只能修复后续语句,但前面的数据已经写入乱码。

坑 3:挂载 my.cnf 配置文件

yaml 复制代码
volumes:
  - ./mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf

结果:

arduino 复制代码
World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored.

Windows 挂载到 Docker 后文件权限变成 777,MySQL 出于安全考虑直接忽略该配置。

坑 4:使用 --skip-character-set-client-handshake

yaml 复制代码
command: >
  --skip-character-set-client-handshake

结果:这个参数确实能让客户端强制使用 server 字符集,但 entrypoint 执行初始化脚本时可能尚未生效,导致初始化数据仍然乱码。

正确解决方案

方案:Shell 脚本包装器(推荐)

创建 00-init-database.sh,显式指定 --default-character-set=utf8mb4 执行 SQL:

bash 复制代码
#!/bin/bash
set -e

# 使用 utf8mb4 字符集执行初始化 SQL
mysql -uroot -p"$MYSQL_ROOT_PASSWORD" --default-character-set=utf8mb4 < /docker-entrypoint-initdb.d/01-init.sql

SQL 文件(01-init.sql):

sql 复制代码
USE `ry-vue`;

-- 建表 + 插入数据...

关键点

  1. .sh 脚本在 .sql 之前执行(按文件名排序)
  2. mysql 命令显式指定 --default-character-set=utf8mb4
  3. SQL 文件中包含 USE db_name;

完整 docker-compose.yml 配置

yaml 复制代码
services:
  mysql:
    image: docker.1ms.run/mysql:8.0
    container_name: ruoyi-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ruoyi123456
      MYSQL_DATABASE: ry-vue
      TZ: Asia/Shanghai
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --default-time-zone=+08:00
    volumes:
      - ./mysql_data:/var/lib/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306"

目录结构

csharp 复制代码
docker/mysql/init/
├── 00-init-database.sh    # Shell 包装器(关键!)
└── 01-init.sql            # 数据库初始化 SQL

验证方法

1. 检查 MySQL 字符集

bash 复制代码
docker exec ruoyi-mysql mysql -uroot -p -e "SHOW VARIABLES LIKE 'character_set%';"

期望结果:

diff 复制代码
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_client     | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database   | utf8mb4 |
| character_set_results    | utf8mb4 |
| character_set_server     | utf8mb4 |
+--------------------------+---------+

2. 检查数据是否正确

bash 复制代码
docker exec ruoyi-mysql sh -c 'mysql -uroot -p -e "SELECT dept_name FROM \`ry-vue\`.sys_dept WHERE dept_id=100;"'

期望结果:

复制代码
dept_name
若依科技
  • 编码 :选择 Autoutf8mb4
  • 高级编码65001 (UTF-8)

总结

方案 效果 原因
--character-set-server=utf8mb4 ❌ 无效 只影响 server,不影响初始化客户端
SQL 中加 SET NAMES utf8mb4 ❌ 无效 执行时已用 latin1 连接
挂载 my.cnf ❌ 无效 Windows 权限问题被忽略
--skip-character-set-client-handshake ⚠️ 不稳定 entrypoint 执行时机不确定
Shell 脚本 + --default-character-set=utf8mb4 有效 直接控制初始化连接的字符集

一句话总结

Docker 部署 MySQL 时,初始化 SQL 一定要用 Shell 脚本包装,显式指定 --default-character-set=utf8mb4,否则中文必乱码!


踩坑不易,如果对你有帮助,欢迎点赞收藏!

相关推荐
hj28625120 分钟前
Docker 容器化技术标准化笔记
java·笔记·docker
潘正翔38 分钟前
docker基础_镜像使用
linux·运维·服务器·docker·容器·centos·devops
江湖有缘1 小时前
Lunalytics部署指南:使用Docker快速搭建私有监控面板
运维·docker·容器
分布式存储与RustFS2 小时前
RustFS保姆级教程:Docker快速部署兼容S3的本地对象存储
运维·docker·容器·rustfs部署教程·本地搭建s3对象存储·rustfs网页控制台使用·awscli连接rustfs
江湖有缘2 小时前
Docker部署Papra极简文件归档平台
运维·docker·容器
艾文伯特3 小时前
k8s-1.35-centos7-安装文档
云原生·容器·kubernetes
qq_349447953 小时前
十四、k8s集群安装kube-state-metrics 组件
docker·容器·kubernetes
必胜刻4 小时前
从零搭建全栈博客系统:Go + Vue 3 + Docker 全流程实战
vue.js·docker·golang
我叫张小白。4 小时前
Docker镜像构建原理与Dockerfile工程化实践深度剖析
运维·docker·容器
艾文伯特4 小时前
k8s-1.35-ubuntu-安装文档.md
ubuntu·容器·kubernetes