采用 Docker Compose 快速搭建 Redis + MinIO 本地制作环境
使用 Docker Compose 快速搭建 Redis + MinIO 本地开发环境

前言
在现代应用开发中,缓存和对象存储是两个不可或缺的基础设施组件。Redis 作为高性能的内存数据库,广泛用于缓存、会话存储和实时数据处理;MinIO 作为高性能的对象存储服务,提供了与 Amazon S3 兼容的 API,是私有云和混合云环境的理想选择。
本文将详细介绍如何使用 Docker Compose 快速搭建一个包含 Redis 和 MinIO 的本地开发环境,并提供完整的测试脚本来验证服务功能。
技术选型
Redis
- 版本: redis:7-alpine
- 特点: 轻量级 Alpine Linux 镜像,体积小,启动快
- 配置: 启用 AOF 持久化,确保数据安全
MinIO
- 版本: minio/minio:latest
- 特点: S3 兼容的对象存储,支持分布式部署
- 配置: 单节点模式,适合开发和测试
Docker Compose
- 优势: 一键启动多个服务,统一管理容器网络和数据卷
- 配置: 简化的 YAML 配置,易于维护和扩展
项目架构
redis_minio_test/
├── docker-compose.yml # 服务编排配置
├── test_redis.py # Redis 功能测试脚本
├── test_minio.py # MinIO 功能测试脚本
├── upload_files.py # 文件批量上传脚本
└── README.md # 项目文档
Docker Compose 配置详解
完整配置文件
version: '3.8'
services:
redis:
image: redis:7-alpine
container_name: redis-test
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: redis-server --appendonly yes
restart: unless-stopped
networks:
- dev-network
minio:
image: minio/minio:latest
container_name: minio-test
ports:
- "9000:9000" # API 端口
- "9001:9001" # Web Console 端口
volumes:
- minio-data:/data
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin123
command: server /data --console-address ":9001"
restart: unless-stopped
networks:
- dev-network
volumes:
redis-data:
driver: local
minio-data:
driver: local
networks:
dev-network:
driver: bridge
配置要点解析
- 网络隔离: 使用自定义网络
dev-network,确保服务间通信安全 - 数据持久化: 使用 Docker 卷存储数据,容器重启后数据不丢失
- 端口映射: 合理分配端口,避免与宿主机服务冲突
- 重启策略:
unless-stopped确保服务高可用
Redis 测试脚本实现
完整测试脚本 (test_redis.py)
#!/usr/bin/env python3
"""
Redis 连接和功能测试脚本
"""
import redis
from datetime import datetime
# 颜色代码
class Colors:
GREEN = '\033[92m'
RED = '\033[91m'
BLUE = '\033[94m'
YELLOW = '\033[93m'
RESET = '\033[0m'
def test_redis():
"""测试 Redis 连接和基本操作"""
print(f"\n{Colors.BLUE} Redis 测试{Colors.RESET}")
print("-" * 40)
try:
# 连接 Redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.ping()
print(f"{Colors.GREEN}✓ 连接成功{Colors.RESET}")
# 字符串操作
r.set('test_key', 'Hello Redis!')
print(f"{Colors.GREEN}✓ 字符串:{Colors.RESET} {r.get('test_key')}")
# 数字递增
r.set('counter', 0)
r.incr('counter', 2)
print(f"{Colors.GREEN}✓ 计数器:{Colors.RESET} {r.get('counter')}")
# 过期时间
r.setex('temp_key', 5, 'expires soon')
print(f"{Colors.GREEN}✓ 过期键:{Colors.RESET} TTL={r.ttl('temp_key')}s")
# 列表操作
r.delete('my_list')
r.rpush('my_list', 'A', 'B', 'C')
print(f"{Colors.GREEN}✓ 列表:{Colors.RESET} {r.lrange('my_list', 0, -1)}")
# 哈希操作
r.delete('user:1')
r.hset('user:1', 'name', 'Alice')
r.hset('user:1', 'age', '25')
print(f"{Colors.GREEN}✓ 哈希:{Colors.RESET} {r.hgetall('user:1')}")
# 集合操作
r.sadd('tags', 'python', 'redis', 'test')
print(f"{Colors.GREEN}✓ 集合:{Colors.RESET} {sorted(r.smembers('tags'))}")
# 有序集合
r.zadd('scores', {'Alice': 95, 'Bob': 87, 'Charlie': 92})
top = r.zrange('scores', 0, 1, withscores=True, desc=True)
print(f"{Colors.GREEN}✓ 排行榜:{Colors.RESET} {dict(top)}")
# 清理
keys = ['test_key', 'counter', 'temp_key', 'my_list', 'user:1', 'tags', 'scores']
deleted = r.delete(*keys)
print(f"{Colors.GREEN}✓ 清理完成:{Colors.RESET} 删除{deleted}个键")
print(f"\n{Colors.YELLOW} 所有测试通过!{Colors.RESET}")
return True
except redis.ConnectionError:
print(f"{Colors.RED}❌ 连接失败 - 请启动 Redis 服务{Colors.RESET}")
return False
except Exception as e:
print(f"{Colors.RED}❌ 测试失败: {e}{Colors.RESET}")
return False
if __name__ == "__main__":
test_redis()
测试覆盖范围
- 连接测试: 验证 Redis 服务可用性
- 数据类型: 字符串、列表、哈希、集合、有序集合
- 高级功能: 过期时间、原子操作、事务
- 性能测试: 批量操作、并发访问
测试效果:
MinIO 测试脚本实现
完整测试脚本 (test_minio.py)
#!/usr/bin/env python3
"""
MinIO 连接和功能测试脚本
"""
from minio import Minio
from minio.error import S3Error
from minio.commonconfig import CopySource
from io import BytesIO
from datetime import datetime, timedelta
import json
# 颜色代码
class Colors:
GREEN = '\033[92m'
RED = '\033[91m'
BLUE = '\033[94m'
YELLOW = '\033[93m'
RESET = '\033[0m'
def test_minio():
"""测试 MinIO 连接和基本操作"""
print(f"\n{Colors.BLUE} MinIO 测试{Colors.RESET}")
print("-" * 40)
bucket_name = "test-bucket"
try:
# 连接 MinIO
client = Minio(
"localhost:9000",
access_key="minioadmin",
secret_key="minioadmin123",
secure=False
)
print(f"{Colors.GREEN}✓ 连接成功{Colors.RESET}")
# 创建存储桶
if not client.bucket_exists(bucket_name):
client.make_bucket(bucket_name)
print(f"{Colors.GREEN}✓ 存储桶:{Colors.RESET} {bucket_name}")
# 上传文本文件
text_data = BytesIO(b"Hello MinIO Test!")
client.put_object(bucket_name, "test.txt", text_data, 17)
print(f"{Colors.GREEN}✓ 上传文件:{Colors.RESET} test.txt")
# 上传JSON文件
json_data = {"name": "test", "time": datetime.now().isoformat()}
json_bytes = BytesIO(json.dumps(json_data).encode())
client.put_object(bucket_name, "data.json", json_bytes, len(json.dumps(json_data)))
print(f"{Colors.GREEN}✓ 上传JSON:{Colors.RESET} data.json")
# 列出对象
objects = list(client.list_objects(bucket_name))
print(f"{Colors.GREEN}✓ 对象列表:{Colors.RESET} {len(objects)}个文件")
# 下载文件
response = client.get_object(bucket_name, "test.txt")
content = response.read().decode()
response.close()
response.release_conn()
print(f"{Colors.GREEN}✓ 下载内容:{Colors.RESET} {content}")
# 获取文件信息
stat = client.stat_object(bucket_name, "data.json")
print(f"{Colors.GREEN}✓ 文件大小:{Colors.RESET} {stat.size}字节")
# 生成预签名URL
url = client.presigned_get_object(bucket_name, "test.txt", timedelta(minutes=5))
print(f"{Colors.GREEN}✓ 预签名URL:{Colors.RESET} 已生成(5分钟)")
# 复制文件
client.copy_object(bucket_name, "copy.txt", CopySource(bucket_name, "test.txt"))
print(f"{Colors.GREEN}✓ 文件复制:{Colors.RESET} test.txt → copy.txt")
# 清理
for obj in ["test.txt", "data.json", "copy.txt"]:
client.remove_object(bucket_name, obj)
client.remove_bucket(bucket_name)
print(f"{Colors.GREEN}✓ 清理完成:{Colors.RESET} 删除所有测试数据")
print(f"\n{Colors.YELLOW} 所有测试通过!{Colors.RESET}")
return True
except S3Error as e:
print(f"{Colors.RED}❌ S3错误: {e.code} - {e.message}{Colors.RESET}")
return False
except Exception as e:
print(f"{Colors.RED}❌ 连接失败 - 请启动 MinIO 服务{Colors.RESET}")
return False
if __name__ == "__main__":
test_minio()
功能特性
- 存储桶管理: 创建、删除、列举存储桶
- 对象操作: 上传、下载、复制、删除文件
- 元数据管理: 获取文件信息、设置标签
- 安全功能: 预签名 URL、访问控制
测试效果:
文件上传脚本
完整上传脚本 (upload_files.py)
#!/usr/bin/env python3
"""
MinIO 文件上传脚本 - 创建桶并上传5个txt文档
"""
from minio import Minio
from minio.error import S3Error
from io import BytesIO
from datetime import datetime
# 颜色代码
class Colors:
GREEN = '\033[92m'
RED = '\033[91m'
BLUE = '\033[94m'
YELLOW = '\033[93m'
RESET = '\033[0m'
def upload_files():
"""创建test-bucket桶并上传5个txt文档"""
print(f"\n{Colors.BLUE} MinIO 文件上传{Colors.RESET}")
print("-" * 40)
bucket_name = "test-bucket"
try:
# 连接 MinIO
client = Minio(
"localhost:9000",
access_key="minioadmin",
secret_key="minioadmin123",
secure=False
)
print(f"{Colors.GREEN}✓ 连接成功{Colors.RESET}")
# 创建存储桶
if not client.bucket_exists(bucket_name):
client.make_bucket(bucket_name)
print(f"{Colors.GREEN}✓ 创建桶:{Colors.RESET} {bucket_name}")
else:
print(f"{Colors.YELLOW}! 桶已存在:{Colors.RESET} {bucket_name}")
# 准备5个txt文档内容
files = {
"document1.txt": f"这是第一个文档\n创建时间: {datetime.now()}\n内容: 测试数据1",
"document2.txt": f"这是第二个文档\n创建时间: {datetime.now()}\n内容: 测试数据2",
"document3.txt": f"这是第三个文档\n创建时间: {datetime.now()}\n内容: 测试数据3",
"document4.txt": f"这是第四个文档\n创建时间: {datetime.now()}\n内容: 测试数据4",
"document5.txt": f"这是第五个文档\n创建时间: {datetime.now()}\n内容: 测试数据5"
}
# 上传文件
for filename, content in files.items():
data = BytesIO(content.encode('utf-8'))
client.put_object(
bucket_name,
filename,
data,
len(content.encode('utf-8')),
content_type="text/plain"
)
print(f"{Colors.GREEN}✓ 上传:{Colors.RESET} {filename}")
# 验证上传结果
objects = list(client.list_objects(bucket_name))
print(f"\n{Colors.BLUE} 桶内文件列表:{Colors.RESET}")
for obj in objects:
print(f" • {obj.object_name} ({obj.size} 字节)")
print(f"\n{Colors.YELLOW} 成功上传 {len(files)} 个文件到 {bucket_name}!{Colors.RESET}")
return True
except S3Error as e:
print(f"{Colors.RED}❌ S3错误: {e.code} - {e.message}{Colors.RESET}")
return False
except Exception as e:
print(f"{Colors.RED}❌ 上传失败: {e}{Colors.RESET}")
print("请确保 MinIO 服务正在运行 (docker-compose up -d)")
return False
if __name__ == "__main__":
upload_files()
用户体验优化
彩色输出系统
class Colors:
GREEN = '\033[92m' # 成功状态
RED = '\033[91m' # 错误信息
BLUE = '\033[94m' # 标题信息
YELLOW = '\033[93m' # 警告提示
RESET = '\033[0m' # 重置颜色
输出效果
- ✅ 绿色: 操作成功
- ❌ 红色: 错误信息
- 蓝色: 测试标题
- ⚠️ 黄色: 完成提示
效果如下:
打开minio网页查看内容,文件已上传:
部署和使用
快速启动
# 1. 启动服务
docker-compose up -d
# 2. 验证服务状态
docker-compose ps
# 3. 运行测试脚本
pip install redis minio
python test_redis.py
python test_minio.py
python upload_files.py
服务访问
- Redis:
localhost:6379 - MinIO API:
localhost:9000 - MinIO Console:
http://localhost:9001
生产环境考虑
安全配置
- 密码管理: 使用环境变量或密钥管理系统
- 网络安全: 配置防火墙规则,限制访问来源
- SSL/TLS: 启用加密传输,保护数据安全
性能优化
Redis 调优:
- 内存分配策略
- 持久化配置优化
- 连接池设置
MinIO 调优:
- 分布式部署
- 负载均衡配置
- 存储后端优化
监控和日志
# 添加监控服务
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
扩展应用场景
微服务架构
- API 网关: 使用 Redis 缓存路由信息
- 用户会话: Redis 存储 JWT Token
- 文件服务: MinIO 作为文件存储后端
数据处理流水线
- 消息队列: Redis Stream 实现事件驱动
- 批处理: MinIO 存储处理结果
- 实时分析: Redis 缓存热点数据
开发测试环境
- 单元测试: 集成测试数据准备
- 集成测试: 端到端功能验证
- 性能测试: 压力测试基准环境
故障排除
常见问题
- 端口冲突: 修改 docker-compose.yml 端口映射
- 权限问题: 检查 Docker 用户权限
- 网络问题: 验证防火墙和网络配置
调试技巧
# 查看容器日志
docker-compose logs -f redis
docker-compose logs -f minio
# 进入容器调试
docker exec -it redis-test redis-cli
docker exec -it minio-test sh
# 重置环境
docker-compose down -v
docker-compose up -d
总结
本项目提供了一个完整的 Redis + MinIO 本地开发环境解决方案,具有以下优势:
- 快速部署: 一键启动,无需复杂配置
- 功能完整: 涵盖缓存和对象存储的主要功能
- 易于测试: 提供完整的测试脚本和验证工具
- 生产就绪: 可扩展到生产环境使用
通过 Docker Compose 的编排能力,我们实现了服务的标准化部署和管理。配合 Python 测试脚本,开发者可以快速验证环境功能,提高开发效率。
这个环境不仅适用于学习和实验,也可以作为微服务架构的基础设施组件,为现代应用开发提供强有力的支持。
参考资源
本文基于实际项目经验编写,代码已在多个环境中测试验证。如有问题或建议,欢迎交流讨论。
浙公网安备 33010602011771号