第一次接触Docker部署MySQL时,我被它的轻量化特性震惊了。传统MySQL安装需要处理各种依赖和配置,而Docker只需要一条命令就能启动一个隔离的数据库环境。这种容器化部署方式特别适合需要快速搭建开发/测试环境的场景。
MySQL作为最流行的关系型数据库之一,在Docker Hub上的官方镜像下载量已突破10亿次。通过Docker部署,我们可以实现:
提示:生产环境建议使用Docker Compose或Kubernetes编排MySQL集群,单容器部署仅适用于开发和测试场景
在开始之前,确保你的系统已经安装Docker Engine。以下是在Ubuntu 20.04上的安装示例:
bash复制# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版仓库
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker引擎
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 验证安装
sudo docker run hello-world
Docker Hub提供了官方MySQL镜像,支持多个版本。建议根据项目需求选择特定版本:
bash复制# 拉取最新版
docker pull mysql:latest
# 拉取指定版本(推荐)
docker pull mysql:8.0.28
# 查看已下载镜像
docker images
注意:生产环境务必指定具体版本号,避免自动升级导致兼容性问题
最简单的启动方式(不推荐用于实际开发):
bash复制docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
这个命令会:
实际开发中我们需要更完善的配置:
bash复制docker run -d \
--name mysql-dev \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=ComplexP@ssw0rd \
-e MYSQL_DATABASE=app_db \
-e MYSQL_USER=dev_user \
-e MYSQL_PASSWORD=User@123 \
-v /opt/mysql/data:/var/lib/mysql \
-v /opt/mysql/conf:/etc/mysql/conf.d \
--restart unless-stopped \
--memory="1g" \
--cpus="1.0" \
mysql:8.0.28 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
参数解析:
-p 3306:3306:端口映射(主机:容器)-e:环境变量配置-v:数据卷挂载(实现数据持久化)--restart:自动重启策略--memory/--cpus:资源限制bash复制# 查看运行中的容器
docker ps
# 查看MySQL容器日志
docker logs mysql-dev
# 进入容器bash环境
docker exec -it mysql-dev bash
预期看到MySQL初始化完成的日志:
code复制[Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server
通过挂载的conf目录(/opt/mysql/conf)可以添加自定义配置:
bash复制# 创建自定义配置文件
vi /opt/mysql/conf/my-custom.cnf
示例配置内容:
ini复制[mysqld]
max_connections = 200
innodb_buffer_pool_size = 512M
query_cache_type = 1
query_cache_size = 64M
slow_query_log = 1
long_query_time = 2
容器默认使用UTC时区,需要显式配置:
bash复制docker run ... -e TZ=Asia/Shanghai ...
或在my.cnf中添加:
ini复制[mysqld]
default-time-zone='+8:00'
根据容器资源限制调整MySQL配置:
innodb_buffer_pool_size:建议为容器内存的50-70%max_connections:开发环境100-200,生产环境根据需求调整tmp_table_size和max_heap_table_size:建议32M-64Mbash复制# 通过docker exec直接连接
docker exec -it mysql-dev mysql -u root -p
# 通过外部客户端连接
mysql -h 127.0.0.1 -P 3306 -u dev_user -p
sql复制-- 查看数据库
SHOW DATABASES;
-- 使用创建的app_db
USE app_db;
-- 创建表
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- 插入数据
INSERT INTO users (username, email)
VALUES ('dev01', 'dev01@example.com');
-- 查询数据
SELECT * FROM users;
bash复制# 备份数据库
docker exec mysql-dev sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /backup/all-databases.sql
# 恢复数据库
cat /backup/all-databases.sql | docker exec -i mysql-dev mysql -uroot -p"$MYSQL_ROOT_PASSWORD"
可能原因及解决方案:
bash复制netstat -tulnp | grep 3306
bash复制chown -R 999:999 /opt/mysql/data
检查步骤:
bash复制docker ps -a
bash复制sudo ufw status
sql复制SELECT host, user FROM mysql.user;
确保:
-v参数挂载数据目录bash复制docker exec mysql-dev mysqladmin -uroot -p shutdown
创建docker-compose.yml:
yaml复制version: '3.8'
services:
mysql:
image: mysql:8.0.28
container_name: mysql-prod
environment:
MYSQL_ROOT_PASSWORD: SecureRootP@ss
MYSQL_DATABASE: app_prod
MYSQL_USER: prod_user
MYSQL_PASSWORD: User@456
TZ: Asia/Shanghai
volumes:
- /data/mysql:/var/lib/mysql
- /data/mysql-conf:/etc/mysql/conf.d
ports:
- "3306:3306"
restart: always
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 3
启动服务:
bash复制docker-compose up -d
使用内置工具:
sql复制-- 查看运行状态
SHOW STATUS;
-- 查看进程列表
SHOW PROCESSLIST;
-- 查看引擎状态
SHOW ENGINE INNODB STATUS;
外部监控方案:
bash复制# 查看容器资源使用
docker stats mysql-dev
# 安装监控工具
docker run -d --name mysql-monitor \
--link mysql-dev:mysql \
-p 8080:3000 \
-e DATA_SOURCE_NAME="root:password@(mysql:3306)/" \
prom/mysqld-exporter
bash复制docker network create mysql-net
docker run --network mysql-net ...
在团队协作环境中,我们通常会建立标准化的MySQL容器配置模板。以下是我的几点实践经验:
版本控制:将docker-compose.yml和自定义配置纳入Git仓库管理,确保团队环境一致
初始化脚本:通过挂载SQL脚本实现自动初始化
yaml复制volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
测试数据隔离:为每个开发者创建独立的数据库实例
sql复制CREATE DATABASE dev_user1;
GRANT ALL PRIVILEGES ON dev_user1.* TO 'user1'@'%';
性能测试:在容器中运行基准测试
bash复制docker exec mysql-dev mysqlslap \
--concurrency=50 \
--iterations=10 \
--query="SELECT * FROM large_table" \
-u root -p
CI/CD集成:在流水线中使用临时MySQL容器进行测试
yaml复制services:
mysql:
image: mysql:8.0.28
environment:
MYSQL_ROOT_PASSWORD: test
MYSQL_DATABASE: test_db
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "mysqladmin", "ping"]