MySQL 8.4 Docker Compose 部署指南

使用 Docker Compose 一键部署 MySQL 8.4 LTS(官方镜像 `mysql:8.4`),涵盖数据目录持久化、常用环境变量与参数配置、健康检查,并给出等价的 `docker run` 运行方式。本文档已在 `/opt/data/ops/mysql` 目录实测通过

MySQLMySQL安装部署容器化2026/09/27

MySQL 8.4 Docker Compose 部署指南

目标:使用 Docker Compose 一键部署 MySQL 8.4 LTS(官方镜像 mysql:8.4),涵盖数据目录持久化、常用环境变量与参数配置、健康检查,并给出等价的 docker run 运行方式。本文档已在 /opt/data/ops/mysql 目录实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • 系统架构:x86_64
  • Docker 版本:Docker Engine 27.x(含 Compose v2 插件)
  • 镜像版本:mysql:8.4(对应 MySQL 8.4.11 LTS,与《Ubuntu 22.04 安装 MySQL 8.0 指南》方案二版本一致)
  • 容器名称:mysql-8-4
  • 端口映射:宿主机 13306 → 容器 3306
  • 数据目录:宿主机 /opt/data/ops/mysql/data(挂载到容器 /var/lib/mysql)
  • 部署文件:/opt/data/ops/mysql/docker-compose.yaml

二、镜像选型说明

镜像标签对应版本特点
mysql:8.4MySQL 8.4 LTS(当前最新 LTS 系列)长期支持,官方维护
mysql:8.0MySQL 8.0 系列(已进入生命周期末期)老版本,缺少新特性与长期安全更新
mysql:latest最新稳定版(当前指向 8.4 LTS)版本会随上游变化,不建议生产锁定

💡 说明:官方镜像仓库为 docker.io/library/mysql。国内拉取可配置阿里云 / daocloud 镜像加速器,或通过中转节点拉取后 docker load 导入宿主机(本文档实测即采用此方式,镜像已 load 到宿主机)。

三、前置条件

  • 已安装 Docker Engine 与 Docker Compose 插件:docker --version && docker compose version
  • 已规划数据目录(建议放在独立磁盘,避免系统盘被数据占满)
  • 已准备好强密码(禁止使用默认/弱密码,见"六、常用环境变量表"章节)

四、部署步骤

4.1 创建部署目录

sudo mkdir -p /opt/data/ops/mysql
cd /opt/data/ops/mysql

4.2 编写 docker-compose.yaml

将以下内容保存为 /opt/data/ops/mysql/docker-compose.yaml:

# =============================================================================
# MySQL 8.4 (LTS) Docker Compose 部署文件
# 镜像版本:mysql:8.4(对应 MySQL 8.4.11,与《Ubuntu 22.04 安装 MySQL 8.0 指南》方案二一致)
# 使用方式:cd /opt/data/ops/mysql && docker compose up -d
# 密码等敏感值通过环境变量注入,请先 export(见文档"六、常用环境变量表"章节)
# =============================================================================

services:
  mysql:
    # 镜像版本:8.4 LTS 官方镜像(阿里云/daocloud 镜像源可加速拉取)
    image: mysql:8.4

    # 容器名称,方便 docker ps / docker logs 定位
    container_name: mysql-8-4

    # 重启策略:容器异常退出时自动重启(除非手动 stop)
    restart: unless-stopped

    # ---- 常用环境变量配置(值由外部环境变量注入)----
    environment:
      - TZ=Asia/Shanghai                      # 容器时区(与宿主机一致)
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:?请在环境变量中设置}  # root 密码(首次初始化生效)
      - MYSQL_DATABASE=${MYSQL_DATABASE:-app_db}   # 自动创建的默认数据库
      - MYSQL_USER=${MYSQL_USER:-app_user}         # 自动创建的业务用户
      - MYSQL_PASSWORD=${MYSQL_PASSWORD:?请在环境变量中设置}            # 业务用户密码
      - MYSQL_ROOT_HOST=${MYSQL_ROOT_HOST:-%}      # 允许 root 远程登录(% 表示任意主机)

    # ---- 常用配置参数(等价于写进 my.cnf)----
    # 说明:参数已统一放入 ./conf/my.cnf(见下方 volumes 挂载),
    # 修改配置只需编辑该文件后 docker compose restart mysql,无需改 yaml
    command:
      - --character-set-server=utf8mb4        # 默认字符集 UTF-8
      - --collation-server=utf8mb4_unicode_ci # 默认排序规则
      - --default-time-zone=+08:00            # 数据库时区(东八区)
      - --max-connections=200                 # 最大连接数

    # ---- 端口映射:宿主机13306 -> 容器3306 ----
    ports:
      - "13306:3306"

    # ---- 数据持久化(重要)----
    # ./data 为宿主机数据目录,重启容器数据不丢失
    volumes:
      - ./data:/var/lib/mysql
      # ---- 配置文件持久化(重要)----
      # ./conf 为宿主机配置目录,挂载到 /etc/mysql/conf.d 自动加载,
      # 编辑 ./conf/my.cnf 后 docker compose restart mysql 即可生效
      - ./conf:/etc/mysql/conf.d

    # ---- 健康检查:容器内 mysqladmin ping 判断数据库就绪 ----
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-p$$MYSQL_ROOT_PASSWORD"]
      interval: 10s      # 每 10 秒检查一次
      timeout: 5s        # 单次检查超时
      retries: 10        # 连续 10 次失败视为不健康
      start_period: 30s  # 启动后 30 秒才开始检查

    # 容器日志大小限制,防止磁盘被日志占满
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

4.3 设置环境变量并启动

# 注入密码(首次初始化生效,容器重建后需保持一致才能正常读取数据目录)
export MYSQL_ROOT_PASSWORD='your-root-password'
export MYSQL_PASSWORD='your-app-password'

docker compose up -d

💡 说明:${MYSQL_ROOT_PASSWORD:?请在环境变量中设置} 语法表示:若该环境变量未设置,docker compose up 会直接报错退出,防止密码缺失导致初始化失败或使用默认值。

4.4 验证部署

# 查看容器状态(healthy 表示健康检查通过)
docker ps --filter name=mysql-8-4

# 连接测试
docker exec -it mysql-8-4 mysql -uroot -p

# 验证字符集与时区
mysql> SHOW VARIABLES LIKE 'character_set_server';
mysql> SHOW VARIABLES LIKE 'time_zone';

五、数据持久化说明

  • 数据目录映射:./data:/var/lib/mysql,MySQL 的库表数据、ibdata、binlog 等全部落在宿主机 ./data 目录。
  • 配置目录映射:./conf:/etc/mysql/conf.d,自定义配置落在宿主机 ./conf 目录,修改后重启容器生效(见"八、配置文件持久化"章节)。
  • 重启容器(docker compose restart / docker compose up -d)数据不丢失。
  • 删除容器不会删除数据:docker compose down 只移除容器,卷目录 ./data 与 ./conf 仍在;只有 docker compose down -v 才会删除卷数据。
  • 备份:直接对宿主机 ./data 目录做快照/rsync 即可(建议配合 mysqldump 逻辑备份双保险)。
  • 权限说明:mysql:8.4 镜像内 MySQL 以 mysql 用户(uid 999)运行,首次启动时镜像会自动对挂载目录做 chown,无需手动处理权限。

六、常用环境变量表

环境变量默认值说明
MYSQL_ROOT_PASSWORD(必填,无默认)root 用户密码,仅首次初始化数据目录时生效
MYSQL_DATABASEapp_db首次初始化自动创建的数据库名
MYSQL_USERapp_user自动创建的业务用户名(与 MYSQL_DATABASE 授权)
MYSQL_PASSWORD(必填,无默认)业务用户密码
MYSQL_ROOT_HOST%允许 root 远程登录的主机(% 表示任意主机,仅建议内网使用)
TZ镜像默认(UTC)容器时区,建议与宿主机一致

⚠️ 安全提醒:MYSQL_ROOT_PASSWORD / MYSQL_PASSWORD 属于敏感值,务必通过环境变量注入,禁止写入 yaml 明文。生产环境可用 Docker secrets 或密码管理工具注入。

七、常用配置参数说明(command)

参数说明
--character-set-server=utf8mb4默认字符集,UTF-8 全量(推荐,避免中文乱码)
--collation-server=utf8mb4_unicode_ci默认排序规则
--default-time-zone=+08:00数据库会话时区(东八区),与 TZ 配合
--max-connections=200最大连接数,按业务规模调整(默认 151)

💡 说明:command 中的参数等价于写入 my.cnf 的 [mysqld] 段。本部署方案已将上述参数同步放入配置文件 ./conf/my.cnf(见下方"八、配置文件持久化"章节),改参数只需编辑该文件后重启容器。

八、配置文件持久化(conf 挂载)

本方案在 volumes 中挂载了配置目录 ./conf:/etc/mysql/conf.d,实现配置文件持久化,方便后续修改参数而无需改动 yaml:

# 配置文件位于宿主机,可随时编辑
sudo vim /opt/data/ops/mysql/conf/my.cnf

./conf/my.cnf 内容如下([mysqld] 段,与 command 参数保持一致,另附更多常用参数示例):

# MySQL 自定义配置文件(挂载到 /etc/mysql/conf.d/my.cnf,自动加载)
# 修改后重启容器生效:docker compose restart mysql

[mysqld]
# 默认字符集 UTF-8 全量
character-set-server = utf8mb4
# 默认排序规则
collation-server = utf8mb4_unicode_ci
# 数据库会话时区(东八区)
default-time-zone = +08:00
# 最大连接数(默认 151)
max_connections = 200

# 更多常用参数示例(按需取消注释):
# innodb_buffer_pool_size = 1G        # InnoDB 缓冲池(建议为物理内存的 60%~70%)
# max_allowed_packet = 64M            # 最大单包大小(大字段/大结果集场景)
# slow_query_log = 1                  # 开启慢查询日志
# long_query_time = 2                 # 慢查询阈值(秒)

💡 说明:镜像会读取 /etc/mysql/conf.d/ 下所有 .cnf 文件并追加合并到主配置,无需修改主配置。修改后执行 docker compose restart mysql 即生效(已验证)。

九、等价 docker run 运行方式

不使用 Compose 时,可用以下 docker run 达到相同效果:

# 先注入环境变量
export MYSQL_ROOT_PASSWORD='your-root-password'
export MYSQL_PASSWORD='your-app-password'

docker run -d \
  --name mysql-8-4 \
  --restart unless-stopped \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD="$MYSQL_ROOT_PASSWORD" \
  -e MYSQL_DATABASE=app_db \
  -e MYSQL_USER=app_user \
  -e MYSQL_PASSWORD="$MYSQL_PASSWORD" \
  -e MYSQL_ROOT_HOST='%' \
  -p 13306:3306 \
  -v /opt/data/ops/mysql/data:/var/lib/mysql \
  -v /opt/data/ops/mysql/conf:/etc/mysql/conf.d \
  --health-cmd='mysqladmin ping -h 127.0.0.1 -uroot -p"$MYSQL_ROOT_PASSWORD"' \
  --health-interval=10s \
  --health-timeout=5s \
  --health-retries=10 \
  --health-start-period=30s \
  mysql:8.4 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci \
  --default-time-zone=+08:00 \
  --max-connections=200

参数对照:

Compose 写法docker run 写法
image: mysql:8.4末尾镜像名 mysql:8.4
container_name--name
restart: unless-stopped--restart unless-stopped
environment-e KEY=value
ports: "13306:3306"-p 13306:3306
volumes: ./data:/var/lib/mysql-v /opt/data/ops/mysql/data:/var/lib/mysql
volumes: ./conf:/etc/mysql/conf.d-v /opt/data/ops/mysql/conf:/etc/mysql/conf.d
healthcheck--health-cmd / --health-interval 等
command镜像名之后的附加参数

💡 说明:--health-cmd 中 "$MYSQL_ROOT_PASSWORD" 会被 shell 展开为容器内环境变量值,故无需转义 $(与 Compose 中需 $$ 转义不同)。

十、常用运维命令

# 查看日志
docker logs -f mysql-8-4

# 重启容器(数据保留)
docker compose restart

# 停止并移除容器(保留数据)
docker compose down

# 彻底移除容器 + 数据目录(谨慎操作!)
docker compose down -v

十一、常见问题(FAQ)

11.1 端口映射失败:宿主机 13306 已被占用?

修改 ports 为其他宿主机端口,如 "13307:3306"。注意客户端连接地址随之变化。

11.2 修改密码后连接报 Access denied?

  • MYSQL_ROOT_PASSWORD 只在首次初始化数据目录时生效;数据目录已存在时修改该变量不会改变 root 密码。
  • 已部署后改密请用 SQL:ALTER USER 'root'@'%' IDENTIFIED BY '新密码'; FLUSH PRIVILEGES;。

11.3 容器反复重启、日志报权限错误?

检查挂载目录权限:sudo chown -R 999:999 /opt/data/ops/mysql/data(uid 999 为镜像内 mysql 用户),或删除损坏的 ./data 目录后重新初始化。

11.4 中文乱码?

确认已传 --character-set-server=utf8mb4,且建库时指定字符集:

CREATE DATABASE app_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

11.5 如何自定义更多参数?

本方案已挂载配置目录 ./conf:/etc/mysql/conf.d,直接编辑 ./conf/my.cnf 的 [mysqld] 段追加参数(如 innodb_buffer_pool_size、slow_query_log),然后 docker compose restart mysql 即生效,无需改动 yaml。镜像会自动加载 /etc/mysql/conf.d/ 下的所有 .cnf 文件并合并到主配置。

MySQL 8.4 Docker Compose 部署指南 - Quzuo