Skip to content

部署 MySQL

快速启动

bash
docker run -d \
  --name mysql \
  --restart unless-stopped \
  -e MYSQL_ROOT_PASSWORD=root123 \
  -e MYSQL_DATABASE=mydb \
  -e MYSQL_USER=myuser \
  -e MYSQL_PASSWORD=mypassword \
  -p 3306:3306 \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

环境变量说明

变量必须说明
MYSQL_ROOT_PASSWORDroot 用户密码
MYSQL_DATABASE自动创建的数据库名
MYSQL_USER创建普通用户
MYSQL_PASSWORD普通用户密码
MYSQL_ALLOW_EMPTY_PASSWORD允许空密码(不推荐)
MYSQL_RANDOM_ROOT_PASSWORD随机生成 root 密码

连接 MySQL

bash
# 进入容器连接
docker exec -it mysql mysql -uroot -proot123

# 使用宿主机 MySQL 客户端(需要安装)
mysql -h 127.0.0.1 -P 3306 -uroot -proot123

# 在另一个容器中连接(通过容器名)
docker run --rm \
  --network 容器所在网络 \
  mysql:8.0 \
  mysql -hmysql -uroot -proot123

自定义配置

bash
# 创建自定义配置文件
cat > ./my.cnf <<'EOF'
[mysqld]
# 字符集
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

# 连接数
max_connections=500

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

# InnoDB 配置
innodb_buffer_pool_size=256M
innodb_log_file_size=64M

# 时区
default-time-zone='+08:00'

[mysql]
default-character-set=utf8mb4

[client]
default-character-set=utf8mb4
EOF

# 挂载自定义配置
docker run -d \
  --name mysql \
  --restart unless-stopped \
  -e MYSQL_ROOT_PASSWORD=root123 \
  -e MYSQL_DATABASE=mydb \
  -p 3306:3306 \
  -v mysql-data:/var/lib/mysql \
  -v $(pwd)/my.cnf:/etc/mysql/conf.d/custom.cnf:ro \
  mysql:8.0

初始化 SQL

.sql 文件放到 /docker-entrypoint-initdb.d/ 目录,MySQL 首次启动时自动执行:

bash
mkdir -p ./initdb

cat > ./initdb/01-init.sql <<'EOF'
CREATE DATABASE IF NOT EXISTS app DEFAULT CHARACTER SET utf8mb4;
CREATE DATABASE IF NOT EXISTS test DEFAULT CHARACTER SET utf8mb4;

GRANT ALL PRIVILEGES ON app.* TO 'myuser'@'%';
FLUSH PRIVILEGES;
EOF

docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=root123 \
  -e MYSQL_USER=myuser \
  -e MYSQL_PASSWORD=mypassword \
  -v mysql-data:/var/lib/mysql \
  -v $(pwd)/initdb:/docker-entrypoint-initdb.d:ro \
  mysql:8.0

数据备份与恢复

bash
# 备份所有数据库
docker exec mysql mysqldump \
  -uroot -proot123 \
  --all-databases \
  --single-transaction \
  > backup_$(date +%Y%m%d).sql

# 备份指定数据库
docker exec mysql mysqldump \
  -uroot -proot123 \
  --single-transaction \
  mydb > mydb_backup.sql

# 恢复数据库
docker exec -i mysql mysql \
  -uroot -proot123 \
  < backup.sql

# 恢复指定数据库
docker exec -i mysql mysql \
  -uroot -proot123 \
  mydb < mydb_backup.sql

使用 Docker Compose

yaml
services:
  mysql:
    image: mysql:8.0
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
      - ./my.cnf:/etc/mysql/conf.d/custom.cnf:ro
      - ./initdb:/docker-entrypoint-initdb.d:ro
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

volumes:
  mysql-data:

常见问题

连接被拒绝(Host is not allowed to connect)

sql
-- 允许所有 IP 连接(开发用,生产环境指定 IP)
ALTER USER 'root'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
FLUSH PRIVILEGES;

字符集问题(中文乱码)

确保配置 character-set-server=utf8mb4collation-server=utf8mb4_unicode_ci

数据目录已存在时环境变量不生效

MySQL 初始化脚本只在数据目录为空时执行,如果 volume 已有数据,环境变量中的初始化设置不再生效。解决:删除 volume 重新创建,或手动执行 SQL。