实战:搭建数据库环境
嘿!长安来教你用Docker搭建各种数据库!再也不用在本地装一堆数据库了!🗄️
🎯 为什么用Docker跑数据库?
优点
✅ 快速部署:一行命令,数据库就起来了
✅ 版本隔离:可以同时跑MySQL 5.7和8.0
✅ 环境一致:开发、测试、生产用同样的配置
✅ 易于清理:不要了就删,干干净净
注意事项
⚠️ 生产环境请谨慎:数据库对性能要求高,生产环境建议用专用服务器
⚠️ 数据备份很重要:一定要做好数据备份!
📦 MySQL
基本使用
# 运行MySQL 8.0
docker run -d \
--name mysql \
-e MYSQL_ROOT_PASSWORD=root123 \
-e MYSQL_DATABASE=mydb \
-e MYSQL_USER=user \
-e MYSQL_PASSWORD=pass123 \
-p 3306:3306 \
-v mysql-data:/var/lib/mysql \
mysql:8.0
# 连接MySQL
docker exec -it mysql mysql -uroot -proot123
# 或使用MySQL客户端
mysql -h 127.0.0.1 -P 3306 -uuser -ppass123
完整的docker-compose配置
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root123}
MYSQL_DATABASE: ${MYSQL_DATABASE:-mydb}
MYSQL_USER: ${MYSQL_USER:-user}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-pass123}
ports:
- "3306:3306"
volumes:
# 数据持久化
- mysql-data:/var/lib/mysql
# 自定义配置
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
# 初始化脚本
- ./mysql/init:/docker-entrypoint-initdb.d
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --default-authentication-plugin=mysql_native_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
volumes:
mysql-data:
自定义配置:mysql/my.cnf
[mysqld]
# 字符集
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 性能优化
max_connections=200
innodb_buffer_pool_size=256M
innodb_log_file_size=64M
# 慢查询日志
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
# 二进制日志
log_bin=/var/log/mysql/mysql-bin.log
binlog_format=ROW
expire_logs_days=7
初始化脚本:mysql/init/init.sql
-- 创建表
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入测试数据
INSERT INTO users (name, email) VALUES
('长安', 'changan@example.com'),
('用户1', 'user1@example.com'),
('用户2', 'user2@example.com');
-- 创建索引
CREATE INDEX idx_email ON users(email);
备份和恢复
# 备份
docker exec mysql mysqldump -uroot -proot123 mydb > backup.sql
# 或备份所有数据库
docker exec mysql mysqldump -uroot -proot123 --all-databases > all_databases.sql
# 恢复
docker exec -i mysql mysql -uroot -proot123 mydb < backup.sql
🐘 PostgreSQL
基本使用
# 运行PostgreSQL
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=postgres123 \
-e POSTGRES_USER=user \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
-v postgres-data:/var/lib/postgresql/data \
postgres:15
# 连接PostgreSQL
docker exec -it postgres psql -U user -d mydb
Docker Compose配置
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-user}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres123}
POSTGRES_DB: ${POSTGRES_DB:-mydb}
PGDATA: /var/lib/postgresql/data/pgdata
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
- ./postgres/init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
# pgAdmin - PostgreSQL管理工具
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin
restart: unless-stopped
environment:
PGADMIN_DEFAULT_EMAIL: admin@example.com
PGADMIN_DEFAULT_PASSWORD: admin123
ports:
- "5050:80"
volumes:
- pgadmin-data:/var/lib/pgadmin
depends_on:
- postgres
volumes:
postgres-data:
pgadmin-data:
初始化脚本:postgres/init/init.sql
-- 创建表
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入测试数据
INSERT INTO users (name, email) VALUES
('长安', 'changan@example.com'),
('用户1', 'user1@example.com');
-- 创建索引
CREATE INDEX idx_email ON users(email);
🍃 MongoDB
基本使用
# 运行MongoDB
docker run -d \
--name mongo \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=admin123 \
-e MONGO_INITDB_DATABASE=mydb \
-p 27017:27017 \
-v mongo-data:/data/db \
mongo:6
# 连接MongoDB
docker exec -it mongo mongosh -u admin -p admin123
Docker Compose配置
version: '3.8'
services:
mongo:
image: mongo:6
container_name: mongo
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USER:-admin}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD:-admin123}
MONGO_INITDB_DATABASE: ${MONGO_DATABASE:-mydb}
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
- mongo-config:/data/configdb
- ./mongo/init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
# Mongo Express - MongoDB管理工具
mongo-express:
image: mongo-express:latest
container_name: mongo-express
restart: unless-stopped
ports:
- "8081:8081"
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_ROOT_USER:-admin}
ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_ROOT_PASSWORD:-admin123}
ME_CONFIG_MONGODB_URL: mongodb://${MONGO_ROOT_USER:-admin}:${MONGO_ROOT_PASSWORD:-admin123}@mongo:27017/
depends_on:
- mongo
volumes:
mongo-data:
mongo-config:
初始化脚本:mongo/init/init.js
// 切换到mydb数据库
db = db.getSiblingDB('mydb');
// 创建集合
db.createCollection('users');
// 插入数据
db.users.insertMany([
{
name: '长安',
email: 'changan@example.com',
createdAt: new Date()
},
{
name: '用户1',
email: 'user1@example.com',
createdAt: new Date()
}
]);
// 创建索引
db.users.createIndex({ email: 1 }, { unique: true });
print('✅ 初始化完成!');
🔴 Redis
基本使用
# 运行Redis
docker run -d \
--name redis \
-p 6379:6379 \
-v redis-data:/data \
redis:7-alpine \
redis-server --appendonly yes
# 连接Redis
docker exec -it redis redis-cli
Docker Compose配置
version: '3.8'
services:
redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-redis123}
ports:
- "6379:6379"
volumes:
- redis-data:/data
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
# RedisInsight - Redis管理工具
redis-insight:
image: redislabs/redisinsight:latest
container_name: redis-insight
restart: unless-stopped
ports:
- "8001:8001"
volumes:
- redis-insight-data:/db
volumes:
redis-data:
redis-insight-data:
Redis配置:redis/redis.conf
# 密码
requirepass redis123
# 持久化
appendonly yes
appendfsync everysec
# 最大内存
maxmemory 256mb
maxmemory-policy allkeys-lru
# 慢查询日志
slowlog-log-slower-than 10000
slowlog-max-len 128
🎯 完整的数据库栈
把所有数据库组合在一起:
docker-compose.yml
version: '3.8'
services:
# MySQL
mysql:
image: mysql:8.0
container_name: db-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
networks:
- db-network
# PostgreSQL
postgres:
image: postgres:15-alpine
container_name: db-postgres
restart: unless-stopped
environment:
POSTGRES_PASSWORD: postgres123
POSTGRES_DB: mydb
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- db-network
# MongoDB
mongo:
image: mongo:6
container_name: db-mongo
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: admin123
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
networks:
- db-network
# Redis
redis:
image: redis:7-alpine
container_name: db-redis
restart: unless-stopped
command: redis-server --appendonly yes
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- db-network
# Adminer - 数据库管理工具(支持MySQL、PostgreSQL等)
adminer:
image: adminer:latest
container_name: db-adminer
restart: unless-stopped
ports:
- "8080:8080"
networks:
- db-network
networks:
db-network:
driver: bridge
volumes:
mysql-data:
postgres-data:
mongo-data:
redis-data:
启动和使用
# 启动所有数据库
docker-compose up -d
# 查看状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 访问Adminer管理工具
# 打开浏览器:http://localhost:8080
🔧 实用脚本
备份脚本:backup.sh
#!/bin/bash
BACKUP_DIR="./backups/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
echo "开始备份数据库..."
# 备份MySQL
echo "备份MySQL..."
docker exec db-mysql mysqldump -uroot -proot123 --all-databases > "$BACKUP_DIR/mysql.sql"
# 备份PostgreSQL
echo "备份PostgreSQL..."
docker exec db-postgres pg_dumpall -U postgres > "$BACKUP_DIR/postgres.sql"
# 备份MongoDB
echo "备份MongoDB..."
docker exec db-mongo mongodump --out=/tmp/backup
docker cp db-mongo:/tmp/backup "$BACKUP_DIR/mongo"
# 备份Redis
echo "备份Redis..."
docker exec db-redis redis-cli SAVE
docker cp db-redis:/data/dump.rdb "$BACKUP_DIR/redis.rdb"
echo "✅ 备份完成!保存在 $BACKUP_DIR"
监控脚本:monitor.sh
#!/bin/bash
echo "====== 数据库监控 ======"
echo
# MySQL状态
echo "MySQL:"
docker exec db-mysql mysqladmin -uroot -proot123 status 2>/dev/null || echo " ❌ 未运行"
echo
# PostgreSQL状态
echo "PostgreSQL:"
docker exec db-postgres pg_isready -U postgres 2>/dev/null || echo " ❌ 未运行"
echo
# MongoDB状态
echo "MongoDB:"
docker exec db-mongo mongosh --eval "db.adminCommand('ping')" 2>/dev/null || echo " ❌ 未运行"
echo
# Redis状态
echo "Redis:"
docker exec db-redis redis-cli ping 2>/dev/null || echo " ❌ 未运行"
echo
# 资源使用
echo "====== 资源使用 ======"
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
💡 最佳实践
1. 数据持久化
✅ 总是使用数据卷
volumes:
- mysql-data:/var/lib/mysql # ✅ 好
# 而不是
# - ./data:/var/lib/mysql # ❌ 不推荐(bind mount性能差)
2. 定期备份
# 添加到crontab
0 2 * * * /path/to/backup.sh
3. 资源限制
services:
mysql:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
4. 健康检查
healthcheck:
test: ["CMD", "mysqladmin", "ping"]
interval: 10s
timeout: 5s
retries: 5
5. 不要暴露到公网
# ❌ 不好
ports:
- "0.0.0.0:3306:3306"
# ✅ 好(只监听本地)
ports:
- "127.0.0.1:3306:3306"
💡 小结
今天长安教你搭建数据库环境:
学到的数据库
✅ MySQL
✅ PostgreSQL
✅ MongoDB
✅ Redis
学到的技能
- 快速部署数据库
- 数据持久化
- 初始化脚本
- 备份恢复
- 管理工具使用
🚀 下一步
数据库环境搭建完了!下一章长安教你 微服务架构!
💬 长安的数据库经验:
Docker跑数据库真的太方便了!
以前本地装了MySQL、PostgreSQL、MongoDB、Redis... 系统慢得要死,还经常端口冲突😂
现在全用Docker,需要什么启动什么,不用了就删掉。
但是记住:生产环境的数据库要慎重!
- 数据一定要备份
- 资源一定要够
- 监控一定要做好
开发测试用Docker,爽!
生产环境看情况,谨慎!下一章见!💪
