一、Docker部署MySQL
1. 快速启动MySQL容器
# 1. 拉取官方镜像(可选,run时会自动拉取)
docker pull mysql:8.0
# 2. 运行MySQL容器
docker run -d \
--name mysql-server \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=your_password \
-e MYSQL_DATABASE=my_database \
-e MYSQL_USER=my_user \
-e MYSQL_PASSWORD=user_password \
--restart=always \
-v mysql_data:/var/lib/mysql \
mysql:8.0 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
# 参数说明:
# -d: 后台运行
# --name: 容器名称
# -p: 端口映射(宿主机:容器)
# -e: 环境变量设置
# --restart=always: 自动重启
# -v: 数据卷挂载(持久化数据)
2. 使用自定义配置文件
# 1. 创建配置文件目录
mkdir -p ~/mysql-docker/conf
mkdir -p ~/mysql-docker/data
# 2. 创建自定义my.cnf
cat > ~/mysql-docker/conf/my.cnf << EOF
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default_authentication_plugin=mysql_native_password
# 性能调优
max_connections=1000
innodb_buffer_pool_size=256M
innodb_log_file_size=48M
slow_query_log=1
long_query_time=2
log-error=/var/log/mysql/error.log
EOF
# 3. 启动容器(使用自定义配置)
docker run -d \
--name mysql-custom \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=root123 \
-v ~/mysql-docker/conf:/etc/mysql/conf.d \
-v ~/mysql-docker/data:/var/lib/mysql \
-v ~/mysql-docker/logs:/var/log/mysql \
mysql:8.0
3. 常用的MySQL容器操作命令
# 查看运行状态
docker ps | grep mysql
# 查看日志
docker logs mysql-server
docker logs -f mysql-server # 实时查看
# 进入容器
docker exec -it mysql-server bash
# 进入MySQL命令行
docker exec -it mysql-server mysql -uroot -p
# 停止容器
docker stop mysql-server
# 启动容器
docker start mysql-server
# 重启容器
docker restart mysql-server
# 删除容器(谨慎操作,数据会丢失除非使用数据卷)
docker rm -f mysql-server
二、制作MySQL自定义镜像
1. 创建Dockerfile
# Dockerfile-mysql-custom
FROM mysql:8.0
LABEL maintainer="yourname@email.com"
LABEL version="1.0"
LABEL description="Custom MySQL image with initialization scripts"
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 复制自定义配置文件
COPY conf/my.cnf /etc/mysql/conf.d/my.cnf
# 复制初始化SQL脚本
COPY init-scripts/ /docker-entrypoint-initdb.d/
# 设置目录权限
RUN chown -R mysql:mysql /docker-entrypoint-initdb.d/
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD mysqladmin ping -h localhost -u root -p${MYSQL_ROOT_PASSWORD} || exit 1
2. 创建初始化脚本
# 创建目录结构
mkdir -p custom-mysql/{conf,init-scripts,sql-scripts}
# 创建初始化数据库脚本
cat > custom-mysql/init-scripts/01-create-databases.sql << 'EOF'
-- 创建业务数据库
CREATE DATABASE IF NOT EXISTS app_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建测试数据库
CREATE DATABASE IF NOT EXISTS test_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建用户并授权(实际生产中使用更安全的密码)
CREATE USER IF NOT EXISTS 'app_user'@'%' IDENTIFIED BY 'app_password';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE ON test_db.* TO 'app_user'@'%';
FLUSH PRIVILEGES;
EOF
# 创建初始化数据脚本
cat > custom-mysql/init-scripts/02-init-tables.sql << 'EOF'
USE app_db;
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 插入测试数据
INSERT IGNORE INTO users (username, email) VALUES
('admin', 'admin@example.com'),
('user1', 'user1@example.com');
EOF
3. 创建配置文件
cat > custom-mysql/conf/my.cnf << 'EOF'
[mysqld]
# 字符集设置
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 连接设置
max_connections=500
wait_timeout=600
interactive_timeout=600
# InnoDB设置
innodb_buffer_pool_size=512M
innodb_log_file_size=128M
innodb_flush_log_at_trx_commit=2
innodb_file_per_table=1
# 日志设置
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=1
log-error=/var/log/mysql/error.log
# 二进制日志(主从复制需要)
# server-id=1
# log-bin=mysql-bin
# binlog_format=row
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
EOF
4. 构建自定义镜像
# 进入项目目录
cd custom-mysql
# 构建镜像
docker build -t my-custom-mysql:1.0 -f Dockerfile .
# 或者直接使用当前目录的Dockerfile
docker build -t my-custom-mysql:1.0 .
# 查看镜像
docker images | grep mysql
5. 测试运行自定义镜像
# 运行自定义镜像
docker run -d \
--name my-mysql \
-p 3310:3306 \
-e MYSQL_ROOT_PASSWORD=Root@123456 \
-v mysql_custom_data:/var/lib/mysql \
-v mysql_custom_logs:/var/log/mysql \
--restart=unless-stopped \
my-custom-mysql:1.0
# 验证初始化数据
docker exec -it my-mysql mysql -uroot -pRoot@123456 -e "SHOW DATABASES;"
docker exec -it my-mysql mysql -uroot -pRoot@123456 -e "USE app_db; SELECT * FROM users;"
三、制作镜像压缩包
1. 保存镜像为tar文件
# 1. 保存镜像到tar文件
docker save -o my-custom-mysql-1.0.tar my-custom-mysql:1.0
# 或者使用gzip压缩(推荐)
docker save my-custom-mysql:1.0 | gzip > my-custom-mysql-1.0.tar.gz
# 2. 查看生成的tar文件
ls -lh my-custom-mysql-*.tar*
2. 从tar文件加载镜像
# 从tar文件加载(未压缩)
docker load -i my-custom-mysql-1.0.tar
# 从压缩文件加载
gunzip -c my-custom-mysql-1.0.tar.gz | docker load
# 或者
docker load < my-custom-mysql-1.0.tar.gz
3. 批量导出多个镜像
# 导出多个镜像到一个文件
docker save -o all-mysql-images.tar \
mysql:8.0 \
my-custom-mysql:1.0 \
mysql:5.7
# 压缩版本
docker save mysql:8.0 my-custom-mysql:1.0 | gzip > mysql-images.tar.gz
4. 镜像导入后验证
# 查看导入的镜像
docker images
# 运行验证
docker run -d --name test-mysql -p 3311:3306 -e MYSQL_ROOT_PASSWORD=test123 my-custom-mysql:1.0
# 验证数据初始化
docker exec test-mysql mysql -uroot -ptest123 -e "SHOW DATABASES;"
四、生产环境部署实践
1. 使用Docker Compose部署
# docker-compose.yml
version: '3.8'
services:
mysql:
image: my-custom-mysql:1.0
container_name: mysql-production
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
TZ: Asia/Shanghai
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- mysql_logs:/var/log/mysql
- ./backup:/backup
networks:
- app-network
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --max_connections=1000
adminer: # 可选:数据库管理工具
image: adminer
restart: always
ports:
- "8080:8080"
networks:
- app-network
volumes:
mysql_data:
mysql_logs:
networks:
app-network:
driver: bridge
2. 环境变量文件
# .env 文件
MYSQL_ROOT_PASSWORD=YourStrongPassword123!
MYSQL_DATABASE=production_db
MYSQL_USER=app_user
MYSQL_PASSWORD=UserPassword456!
3. 部署脚本
#!/bin/bash
# deploy.sh
set -e
echo "=== MySQL Docker 部署脚本 ==="
# 1. 加载镜像
echo "正在加载MySQL镜像..."
docker load -i my-custom-mysql-1.0.tar
# 2. 创建数据目录
mkdir -p /data/mysql/{data,logs,backup}
chmod -R 755 /data/mysql
# 3. 创建网络
docker network create app-network 2>/dev/null || true
# 4. 运行容器
echo "启动MySQL容器..."
docker run -d \
--name mysql-production \
--network app-network \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-Root@123456} \
-e MYSQL_DATABASE=app_production \
-v /data/mysql/data:/var/lib/mysql \
-v /data/mysql/logs:/var/log/mysql \
-v /data/mysql/backup:/backup \
--restart=always \
--health-cmd="mysqladmin ping -h localhost -u root -p${MYSQL_ROOT_PASSWORD:-Root@123456}" \
--health-interval=30s \
--health-timeout=5s \
--health-retries=3 \
my-custom-mysql:1.0
# 5. 验证部署
echo "等待MySQL启动..."
sleep 30
if docker exec mysql-production mysqladmin ping -h localhost -u root -p${MYSQL_ROOT_PASSWORD:-Root@123456} &>/dev/null; then
echo "✓ MySQL部署成功!"
echo "连接信息:"
echo " Host: localhost"
echo " Port: 3306"
echo " Root Password: [请查看.env文件]"
else
echo "✗ MySQL启动失败,请检查日志:"
docker logs mysql-production
exit 1
fi
4. 备份与恢复脚本
#!/bin/bash
# backup.sh
# 备份数据库
BACKUP_DIR="/data/mysql/backup"
DATE=$(date +%Y%m%d_%H%M%S)
CONTAINER_NAME="mysql-production"
# 创建备份目录
mkdir -p ${BACKUP_DIR}
echo "开始备份MySQL数据库..."
# 执行备份
docker exec ${CONTAINER_NAME} \
mysqldump -uroot -p${MYSQL_ROOT_PASSWORD} \
--all-databases \
--single-transaction \
--routines \
--triggers \
--events > ${BACKUP_DIR}/full_backup_${DATE}.sql
# 压缩备份文件
gzip ${BACKUP_DIR}/full_backup_${DATE}.sql
echo "备份完成: ${BACKUP_DIR}/full_backup_${DATE}.sql.gz"
# 删除7天前的备份
find ${BACKUP_DIR} -name "*.sql.gz" -mtime +7 -delete
# 恢复脚本示例
# docker exec -i ${CONTAINER_NAME} mysql -uroot -p${MYSQL_ROOT_PASSWORD} < backup.sql
五、最佳实践建议
1. 安全建议
- 使用强密码生成器创建密码
- 定期更新密码
- 限制root用户远程访问
- 使用专用网络(如Docker network)
- 定期备份数据
2. 性能优化
- 根据服务器内存调整
innodb_buffer_pool_size
- 使用SSD存储提高IO性能
- 适当调整连接数
max_connections
- 启用查询缓存
3. 监控维护
- 监控容器资源使用情况
- 定期检查错误日志
- 设置自动备份策略
- 定期更新镜像版本
4. 迁移步骤
# 1. 在新服务器安装Docker
# 2. 传输镜像文件
scp my-custom-mysql-1.0.tar.gz user@new-server:/tmp/
# 3. 在新服务器加载镜像
docker load < /tmp/my-custom-mysql-1.0.tar.gz
# 4. 迁移数据(如果需要)
# 在原服务器备份数据
# 在新服务器恢复数据
# 5. 更新应用连接配置
这个实践指南涵盖了从基础部署到生产环境的最佳实践,你可以根据实际需求进行调整。