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

 更新时间:2026年05月26日 08:32:30   作者:PythonAI实战君  
本文主要介绍了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 中配置了:

command: >
  --character-set-server=utf8mb4
  --collation-server=utf8mb4_unicode_ci

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

踩坑过程

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

# 错误示范 ❌
command: >
  --character-set-server=utf8mb4
  --collation-server=utf8mb4_unicode_ci

结果:

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

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

-- 无效 ❌
SET NAMES utf8mb4;
SET CHARACTER SET utf8mb4;

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

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

volumes:
  - ./mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf

结果:

World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored.

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

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

command: >
  --skip-character-set-client-handshake

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

正确解决方案

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

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

#!/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):

USE `ry-vue`;
-- 建表 + 插入数据...

关键点:

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

完整 docker-compose.yml 配置

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"

目录结构

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

验证方法

1. 检查 MySQL 字符集

docker exec ruoyi-mysql mysql -uroot -p -e "SHOW VARIABLES LIKE 'character_set%';"

期望结果:

+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_client     | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database   | utf8mb4 |
| character_set_results    | utf8mb4 |
| character_set_server     | utf8mb4 |
+--------------------------+---------+

2. 检查数据是否正确

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

期望结果:

dept_name
若依科技

3. Navicat 连接设置

  • 编码:选择 Auto 或 utf8mb4
  • 高级 → 编码: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,否则中文必乱码!

到此这篇关于Docker Compose 部署 MySQL 中文乱码避坑指南的文章就介绍到这了,更多相关Docker Compose 部署 MySQL 中文乱码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • docker连接spring boot和mysql容器方法介绍

    docker连接spring boot和mysql容器方法介绍

    这篇文章主要介绍了docker连接spring boot和mysql容器方法介绍,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • Dockerfile指令与基本结构的讲解

    Dockerfile指令与基本结构的讲解

    今天小编就为大家分享一篇关于Dockerfile指令与基本结构的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Docker Swarm结合Docker Compose部署集群的实现

    Docker Swarm结合Docker Compose部署集群的实现

    本文主要介绍了Docker Swarm结合Docker Compose部署集群的实现,通过部署和配置帮助读者更好地理解并应用这些工具,感兴趣的可以了解一下
    2023-12-12
  • docker实现重新打tag并删除原tag的镜像

    docker实现重新打tag并删除原tag的镜像

    这篇文章主要介绍了docker实现重新打tag并删除原tag的镜像,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Docker下Tomcat容器中使用Mysql的方法

    Docker下Tomcat容器中使用Mysql的方法

    这篇文章主要介绍了Docker下Tomcat容器中使用Mysql的方法,需要的朋友可以参考下
    2018-07-07
  • Docker开启远程安全访问的图文教程详解

    Docker开启远程安全访问的图文教程详解

    这篇文章主要介绍了Docker开启远程安全访问的详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Docker部署Mysql,.Net6,Sqlserver等容器

    Docker部署Mysql,.Net6,Sqlserver等容器

    这篇文章介绍了Docker部署Mysql,.Net6,Sqlserver等容器的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • Docker 磁盘占用分析和清理方法示例小结

    Docker 磁盘占用分析和清理方法示例小结

    本文介绍Docker磁盘占用分析与清理方法,涵盖镜像、容器、卷及构建缓存的资源排查,提供清理未使用资源的命令及选项,如docker system prune和docker image prune,并解释悬空镜像的产生原因及处理技巧,感兴趣的朋友一起看看吧
    2025-07-07
  • Docker 打包python的命令详解

    Docker 打包python的命令详解

    最近用Python写了一段爬虫程序,为了隔离其运行环境,易于分发,把项目打包成Docker镜像,下面给大家简单介绍下具体命令写法
    2016-12-12
  • Docker部署前后端分离项目的三种方式小结

    Docker部署前后端分离项目的三种方式小结

    本文主要介绍了Docker部署前后端分离项目的三种方式小结,包含通过两个容器部署,通过compose编排容器自动部署和将前后端项目打成一个镜像部署的三种方式,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03

最新评论