采用 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

配置要点解析

  1. 网络隔离: 使用自定义网络 dev-network,确保服务间通信安全
  2. 数据持久化: 使用 Docker 卷存储数据,容器重启后数据不丢失
  3. 端口映射: 合理分配端口,避免与宿主机服务冲突
  4. 重启策略: 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

生产环境考虑

安全配置

  1. 密码管理: 使用环境变量或密钥管理系统
  2. 网络安全: 配置防火墙规则,限制访问来源
  3. SSL/TLS: 启用加密传输,保护数据安全

性能优化

  1. Redis 调优:

    • 内存分配策略
    • 持久化配置优化
    • 连接池设置
  2. 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 缓存热点数据

开发测试环境

  • 单元测试: 集成测试数据准备
  • 集成测试: 端到端功能验证
  • 性能测试: 压力测试基准环境

故障排除

常见问题

  1. 端口冲突: 修改 docker-compose.yml 端口映射
  2. 权限问题: 检查 Docker 用户权限
  3. 网络问题: 验证防火墙和网络配置

调试技巧

# 查看容器日志
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 本地开发环境解决方案,具有以下优势:

  1. 快速部署: 一键启动,无需复杂配置
  2. 功能完整: 涵盖缓存和对象存储的主要功能
  3. 易于测试: 提供完整的测试脚本和验证工具
  4. 生产就绪: 可扩展到生产环境使用

通过 Docker Compose 的编排能力,我们实现了服务的标准化部署和管理。配合 Python 测试脚本,开发者可以快速验证环境功能,提高开发效率。

这个环境不仅适用于学习和实验,也可以作为微服务架构的基础设施组件,为现代应用开发提供强有力的支持。

参考资源


本文基于实际项目经验编写,代码已在多个环境中测试验证。如有问题或建议,欢迎交流讨论。

posted @ 2025-12-11 22:30  clnchanpin  阅读(23)  评论(0)    收藏  举报