摘要
随着人工智能技术的迅猛发展,越来越多的应用需要集成AI功能。Docker Compose作为一种强大的容器编排工具,能够帮助开发者快速搭建和部署复杂的AI应用系统。本文将详细介绍如何使用Docker Compose构建一个包含Redis、Playwright服务、API服务和Worker服务的完整AI应用系统。通过实践示例,我们将展示如何解决常见的部署问题,优化系统性能,并提供最佳实践建议。本文的目标读者是中国开发者,特别是AI应用开发者,旨在帮助他们快速掌握Docker Compose在AI应用开发中的应用。
正文
1. 引言
在当今的软件开发领域,容器化技术已经成为标准实践,特别是在AI应用开发中。AI应用通常涉及多个服务组件,如数据处理服务、模型推理服务、API接口服务等,这些组件需要协同工作才能提供完整的功能。Docker Compose通过一个YAML文件来定义和管理这些多容器应用,极大地简化了复杂系统的部署和维护。
本文将以一个典型的AI爬虫应用为例,深入探讨如何使用Docker Compose构建、部署和优化AI应用系统。我们将逐步介绍环境搭建、服务配置、故障排查和性能优化等关键环节,并提供实际可运行的代码示例。
2. Docker Compose基础概念
2.1 什么是Docker Compose
Docker Compose是Docker官方提供的一个工具,用于定义和运行多容器Docker应用程序。通过使用Compose,您可以使用YAML文件来配置应用程序的服务,然后使用单个命令创建和启动配置中的所有服务。
Docker Compose的主要优势包括:
- 简化配置:通过一个YAML文件定义所有服务
- 一键部署:使用单个命令启动整个应用栈
- 环境隔离:为不同环境提供独立的配置
- 服务编排:管理服务间的依赖关系和启动顺序
2.2 Docker Compose核心概念
- 服务(Service):一个应用容器,实际上就是Docker镜像的一个运行实例
- 项目(Project):由一组关联的应用容器组成的一个完整业务单元
- 卷(Volume):用于持久化数据的机制
- 网络(Network):用于服务间通信的网络配置
3. 环境搭建
3.1 安装Docker和Docker Compose
在开始之前,确保您的系统已经安装了Docker和Docker Compose。以下是Ubuntu系统上的安装步骤:
# 更新包索引
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 Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker --version
docker-compose --version
3.2 项目结构设计
一个典型的AI应用项目结构如下:
ai-app/
├── docker-compose.yml # Docker Compose配置文件
├── .env # 环境变量配置文件
├── src/ # 应用源代码
│ ├── api/ # API服务代码
│ ├── worker/ # Worker服务代码
│ └── playwright-service/ # Playwright服务代码
├── data/ # 数据存储目录
│ ├── redis/ # Redis数据目录
│ └── models/ # AI模型文件目录
└── scripts/ # 辅助脚本目录
├── deploy.sh # 部署脚本
└── monitor.py # 监控脚本
4. Docker Compose配置详解
4.1 核心配置文件
以下是一个完整的Docker Compose配置文件示例,用于部署一个AI爬虫应用:
# docker-compose.yml
version: '3.8'
# 定义通用服务配置
x-common-service: &common-service
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/mendableai/firecrawl:latest
ulimits:
nofile:
soft: 65535
hard: 65535
networks:
- backend
extra_hosts:
- "host.docker.internal:host-gateway"
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
# 定义通用环境变量
x-common-env: &common-env
REDIS_URL: ${REDIS_URL:-redis://redis:6381}
REDIS_RATE_LIMIT_URL: ${REDIS_URL:-redis://redis:6381}
PLAYWRIGHT_MICROSERVICE_URL: ${PLAYWRIGHT_MICROSERVICE_URL:-http://playwright-service:3000/scrape}
USE_DB_AUTHENTICATION: ${USE_DB_AUTHENTICATION:-false}
LOGGING_LEVEL: ${LOGGING_LEVEL:-INFO}
# 定义服务
services:
# Playwright服务 - 用于网页自动化
playwright-service:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/mendableai/playwright-service:latest
environment:
PORT: 3000
PROXY_SERVER: ${PROXY_SERVER:-}
PROXY_USERNAME: ${PROXY_USERNAME:-}
PROXY_PASSWORD: ${PROXY_PASSWORD:-}
BLOCK_MEDIA: ${BLOCK_MEDIA:-true}
networks:
backend:
aliases:
- playwright-service
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
shm_size: 2gb
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (res) => process.exit(res.statusCode < 400 ? 0 : 1))"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
# API服务 - 提供对外接口
api:
<<: *common-service
environment:
<<: *common-env
HOST: 0.0.0.0
PORT: ${PORT:-8083}
FLY_PROCESS_GROUP: app
ENV: local
depends_on:
redis:
condition: service_started
playwright-service:
condition: service_healthy
ports:
- "${PORT:-8083}:${PORT:-8083}"
command: ["pnpm", "run", "start:production"]
deploy:
resources:
limits:
memory: 1G
cpus: '0.5'
# Worker服务 - 处理后台任务
worker:
<<: *common-service
environment:
<<: *common-env
FLY_PROCESS_GROUP: worker
ENV: local
depends_on:
redis:
condition: service_started
playwright-service:
condition: service_healthy
command: ["pnpm", "run", "workers"]
deploy:
replicas: ${NUM_WORKER_REPLICAS:-2}
resources:
limits:
memory: 2G
cpus: '1.0'
# Redis服务 - 用作缓存和任务队列
redis:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/redis:7.0.12
networks:
- backend
ports:
- "6381:6381"
command: redis-server --bind 0.0.0.0 --port 6381
volumes:
- redis-data:/data
deploy:
resources:
limits:
memory: 1G
cpus: '0.5'
# 定义网络
networks:
backend:
driver: bridge
# 定义卷
volumes:
redis-data:
driver: local
4.2 环境变量配置
环境变量文件用于配置应用的各种参数:
# .env 文件
# ===== 必需的环境变量 =====
NUM_WORKER_REPLICAS=2
PORT=8083
HOST=0.0.0.0
REDIS_URL=redis://redis:6381
PLAYWRIGHT_MICROSERVICE_URL=http://playwright-service:3000/scrape
USE_DB_AUTHENTICATION=false
# ===== 可选的环境变量 =====
LOGGING_LEVEL=INFO
PROXY_SERVER=
PROXY_USERNAME=
PROXY_PASSWORD=
BLOCK_MEDIA=true
# ===== 资源限制配置 =====
API_MEMORY_LIMIT=1G
API_CPU_LIMIT=0.5
WORKER_MEMORY_LIMIT=2G
WORKER_CPU_LIMIT=1.0
REDIS_MEMORY_LIMIT=1G
REDIS_CPU_LIMIT=0.5
PLAYWRIGHT_MEMORY_LIMIT=2G
PLAYWRIGHT_CPU_LIMIT=1.0
5. 系统架构设计
5.1 架构图
AI应用系统的整体架构如下图所示:
5.2 各组件功能说明
- API服务:提供RESTful API接口,接收客户端请求并返回处理结果
- Worker服务:处理耗时的后台任务,如网页爬取、数据处理等
- Playwright服务:专门用于网页自动化操作,处理JavaScript渲染的页面
- Redis服务:作为缓存系统和任务队列,协调各服务间的工作
6. Python监控脚本
为了更好地管理和监控Docker Compose部署的AI应用,我们可以编写Python脚本来自动化监控和管理任务:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI应用Docker Compose监控和管理脚本
用于监控服务状态、资源使用情况和执行管理任务
"""
import docker
import time
import json
import os
from typing import Dict, List, Optional
import subprocess
import requests
class AIAppManager:
"""AI应用管理器"""
def __init__(self, project_name: str = "firecrawl"):
"""
初始化AI应用管理器
Args:
project_name (str): Docker Compose项目名称
"""
self.project_name = project_name
try:
self.client = docker.from_env()
print(f"✅ Docker客户端初始化成功")
except Exception as e:
print(f"❌ Docker客户端初始化失败: {e}")
raise
def get_service_status(self) -> List[Dict]:
"""
获取所有服务的状态信息
Returns:
List[Dict]: 服务状态信息列表
"""
try:
# 使用docker-compose命令获取服务状态
result = subprocess.run([
"docker-compose",
"-p", self.project_name,
"ps", "--format", "json"
], capture_output=True, text=True)
if result.returncode == 0:
# 解析JSON输出
services = []
for line in result.stdout.strip().split('\n'):
if line:
service_info = json.loads(line)
services.append(service_info)
return services
else:
print(f"获取服务状态失败: {result.stderr}")
return []
except Exception as e:
print(f"获取服务状态时发生错误: {e}")
return []
def get_container_stats(self, container_name: str) -> Dict:
"""
获取指定容器的资源使用统计信息
Args:
container_name (str): 容器名称
Returns:
Dict: 容器资源使用统计信息
"""
try:
# 获取容器对象
container = self.client.containers.get(container_name)
# 获取容器统计信息
stats = container.stats(stream=False)
# 提取关键资源使用信息
cpu_stats = stats['cpu_stats']
precpu_stats = stats['precpu_stats']
memory_stats = stats['memory_stats']
# 计算CPU使用率
cpu_delta = cpu_stats['cpu_usage']['total_usage'] - precpu_stats['cpu_usage']['total_usage']
system_delta = cpu_stats['system_cpu_usage'] - precpu_stats['system_cpu_usage']
if system_delta > 0 and cpu_delta > 0:
cpu_percent = (cpu_delta / system_delta) * len(cpu_stats['cpu_usage']['percpu_usage']) * 100
else:
cpu_percent = 0.0
# 获取内存使用信息
memory_usage = memory_stats.get('usage', 0) / (1024 * 1024) # 转换为MB
memory_limit = memory_stats.get('limit', 0) / (1024 * 1024) # 转换为MB
memory_percent = (memory_usage / memory_limit) * 100 if memory_limit > 0 else 0
return {
'container_name': container_name,
'cpu_percent': round(cpu_percent, 2),
'memory_usage_mb': round(memory_usage, 2),
'memory_limit_mb': round(memory_limit, 2),
'memory_percent': round(memory_percent, 2),
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
}
except Exception as e:
print(f"获取容器 {container_name} 统计信息失败: {e}")
return {}
def check_service_health(self, service_name: str) -> Dict:
"""
检查服务健康状态
Args:
service_name (str): 服务名称
Returns:
Dict: 健康检查结果
"""
health_checks = {
'api': {'url': 'http://localhost:8083/health', 'expected_status': 200},
'playwright-service': {'url': 'http://localhost:3000', 'expected_status': 200},
'redis': {'host': 'localhost', 'port': 6381}
}
if service_name not in health_checks:
return {'service': service_name, 'status': 'unknown', 'message': '未定义健康检查'}
try:
if service_name == 'redis':
# Redis健康检查
import redis
r = redis.Redis(host=health_checks[service_name]['host'],
port=health_checks[service_name]['port'])
r.ping()
return {'service': service_name, 'status': 'healthy', 'message': 'Redis连接正常'}
else:
# HTTP健康检查
response = requests.get(health_checks[service_name]['url'], timeout=5)
if response.status_code == health_checks[service_name]['expected_status']:
return {'service': service_name, 'status': 'healthy', 'message': '服务运行正常'}
else:
return {'service': service_name, 'status': 'unhealthy', 'message': f'HTTP状态码异常: {response.status_code}'}
except Exception as e:
return {'service': service_name, 'status': 'unhealthy', 'message': f'健康检查失败: {str(e)}'}
def scale_service(self, service_name: str, replicas: int) -> bool:
"""
扩缩容服务
Args:
service_name (str): 服务名称
replicas (int): 副本数量
Returns:
bool: 操作是否成功
"""
try:
result = subprocess.run([
"docker-compose",
"-p", self.project_name,
"up", "-d", "--scale", f"{service_name}={replicas}"
], capture_output=True, text=True)
if result.returncode == 0:
print(f"✅ 服务 {service_name} 已成功扩缩容到 {replicas} 个副本")
return True
else:
print(f"❌ 扩缩容失败: {result.stderr}")
return False
except Exception as e:
print(f"❌ 扩缩容时发生错误: {e}")
return False
def print_service_status(self):
"""打印服务状态表"""
services = self.get_service_status()
if not services:
print("❌ 未获取到服务信息")
return
print("\n" + "="*120)
print(f"{'服务名称':<25} {'状态':<15} {'端口':<20} {'镜像':<40} {'命令':<20}")
print("="*120)
for service in services:
name = service.get('Service', 'N/A')
status = service.get('State', 'N/A')
ports = service.get('Publishers', [])
port_str = ', '.join([f"{p.get('PublishedPort', '')}->{p.get('TargetPort', '')}" for p in ports]) if ports else 'N/A'
image = service.get('Image', 'N/A')[:40]
command = service.get('Command', 'N/A')[:20]
# 根据状态设置颜色
status_display = status
if status == 'running':
status_display = f"🟢 {status}"
elif status in ['exited', 'dead']:
status_display = f"🔴 {status}"
else:
status_display = f"🟡 {status}"
print(f"{name:<25} {status_display:<15} {port_str:<20} {image:<40} {command:<20}")
print("="*120 + "\n")
def monitor_resources(self, service_names: List[str]):
"""
监控指定服务的资源使用情况
Args:
service_names (List[str]): 服务名称列表
"""
print(f"\n[{time.strftime('%Y-%m-%d %H:%M:%S')}] 资源使用情况监控:")
print("-"*100)
print(f"{'容器名称':<25} {'CPU使用率':<15} {'内存使用(MB)':<15} {'内存限制(MB)':<15} {'内存使用率':<15}")
print("-"*100)
for service_name in service_names:
# 获取项目中的容器
try:
containers = self.client.containers.list(filters={
"label": f"com.docker.compose.service={service_name}"
})
for container in containers:
stats = self.get_container_stats(container.name)
if stats:
print(f"{stats['container_name'][:25]:<25} "
f"{stats['cpu_percent']:<15} "
f"{stats['memory_usage_mb']:<15} "
f"{stats['memory_limit_mb']:<15} "
f"{stats['memory_percent']:<15}%")
except Exception as e:
print(f"监控服务 {service_name} 时出错: {e}")
print("-"*100 + "\n")
def main():
"""主函数"""
# 初始化管理器
manager = AIAppManager("firecrawl")
# 定义要监控的服务
services_to_monitor = [
'api',
'worker',
'playwright-service',
'redis'
]
try:
while True:
print(f"\n{'='*50}")
print(f"🤖 AI应用监控面板 - {time.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"{'='*50}")
# 显示服务状态
manager.print_service_status()
# 显示资源使用情况
manager.monitor_resources(services_to_monitor)
# 健康检查
print("🏥 服务健康检查:")
for service in services_to_monitor:
health = manager.check_service_health(service)
status_icon = "✅" if health['status'] == 'healthy' else "❌"
print(f" {status_icon} {health['service']}: {health['message']}")
print(f"\n⏳ 10秒后刷新,按 Ctrl+C 退出...")
time.sleep(10)
except KeyboardInterrupt:
print("\n👋 监控已停止")
except Exception as e:
print(f"❌ 监控过程中发生错误: {e}")
if __name__ == "__main__":
main()
7. 实践案例
7.1 案例背景
假设我们需要开发一个AI网页内容分析应用,该应用能够爬取指定网页,提取关键信息,并使用AI模型进行分析。我们将使用Docker Compose搭建一个包含以下组件的系统:
- API服务:提供RESTful接口接收用户请求
- Worker服务:处理后台爬取和分析任务
- Playwright服务:处理复杂的网页交互
- Redis服务:作为任务队列和缓存
7.2 实施步骤
- 项目初始化
# 创建项目目录
mkdir ai-web-analyzer
cd ai-web-analyzer
# 创建必要的目录结构
mkdir -p src/api src/worker src/playwright-service data/redis
touch docker-compose.yml .env
# 创建Python监控脚本
touch scripts/monitor.py
chmod +x scripts/monitor.py
- 编写Docker Compose文件
参考第4节的配置文件内容。
- 配置环境变量
参考第4.2节的环境变量配置。
- 启动系统
# 启动所有服务
docker-compose -p ai-analyzer up -d
# 查看服务状态
docker-compose -p ai-analyzer ps
# 查看服务日志
docker-compose -p ai-analyzer logs -f
- 验证系统功能
# 测试API服务
curl -X POST http://localhost:8083/v1/scrape \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'
# 测试Redis连接
docker exec -it ai-analyzer-redis-1 redis-cli -p 6381 ping
8. 注意事项
8.1 资源限制配置
合理配置资源限制对于系统稳定性至关重要:
services:
worker:
deploy:
resources:
limits:
memory: 4G # 根据AI模型大小调整
cpus: '2.0' # 根据计算需求调整
reservations:
memory: 2G # 保证最小资源
cpus: '1.0'
8.2 网络配置
确保所有服务在同一个网络中以便相互通信:
networks:
backend:
driver: bridge
8.3 数据持久化
对于需要持久化数据的服务,配置卷映射:
services:
redis:
volumes:
- redis-data:/data
volumes:
redis-data:
driver: local
9. 最佳实践
9.1 使用环境变量管理配置
通过环境变量文件管理配置,便于在不同环境中切换:
# .env
LOGGING_LEVEL=INFO
NUM_WORKER_REPLICAS=3
API_MEMORY_LIMIT=1G
WORKER_MEMORY_LIMIT=4G
9.2 健康检查机制
为每个服务添加健康检查,确保服务正常运行:
services:
playwright-service:
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (res) => process.exit(res.statusCode < 400 ? 0 : 1))"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
9.3 服务依赖管理
使用depends_on确保服务按正确顺序启动:
services:
api:
depends_on:
redis:
condition: service_started
playwright-service:
condition: service_healthy
9.4 日志管理
配置日志驱动以便于问题排查:
services:
api:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
10. 常见问题及解决方案
10.1 服务启动失败
问题现象:服务容器启动后立即退出
解决方案:
- 检查日志:
docker-compose logs service-name - 验证配置:
docker-compose config - 检查端口冲突:确保端口未被占用
10.2 网络连接问题
问题现象:服务间无法通信
解决方案:
- 检查网络配置:确保服务在同一网络中
- 验证服务名称解析:使用服务名称而非IP地址
- 检查防火墙设置:确保端口开放
10.3 资源不足
问题现象:容器被系统终止或性能下降
解决方案:
- 增加资源限制:调整memory和cpus配置
- 优化应用代码:减少内存使用和CPU消耗
- 扩展服务副本:使用–scale参数增加副本数
10.4 数据持久化问题
问题现象:容器重启后数据丢失
解决方案:
- 配置卷映射:将重要数据存储在卷中
- 定期备份:建立数据备份机制
- 使用外部存储:对于重要数据使用外部数据库
11. 性能优化策略
11.1 资源优化
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
资源优化建议脚本
根据系统负载动态调整资源配置
"""
import psutil
import docker
import time
class ResourceOptimizer:
"""资源优化器"""
def __init__(self):
self.client = docker.from_env()
def get_system_load(self):
"""获取系统负载"""
# CPU使用率
cpu_percent = psutil.cpu_percent(interval=1)
# 内存使用率
memory = psutil.virtual_memory()
memory_percent = memory.percent
# 磁盘使用率
disk = psutil.disk_usage('/')
disk_percent = (disk.used / disk.total) * 100
return {
'cpu_percent': cpu_percent,
'memory_percent': memory_percent,
'disk_percent': disk_percent
}
def recommend_scaling(self, service_name: str, current_replicas: int):
"""
根据系统负载推荐扩缩容策略
Args:
service_name (str): 服务名称
current_replicas (int): 当前副本数
Returns:
dict: 扩缩容建议
"""
load = self.get_system_load()
# 简单的负载均衡策略
if load['cpu_percent'] > 80 or load['memory_percent'] > 80:
# 高负载,建议扩容
recommended_replicas = min(current_replicas + 1, 10) # 最多10个副本
action = "scale_up"
elif load['cpu_percent'] < 30 and load['memory_percent'] < 30 and current_replicas > 1:
# 低负载,建议缩容
recommended_replicas = max(current_replicas - 1, 1) # 最少1个副本
action = "scale_down"
else:
# 负载正常,保持现状
recommended_replicas = current_replicas
action = "keep"
return {
'action': action,
'current_replicas': current_replicas,
'recommended_replicas': recommended_replicas,
'system_load': load,
'reason': self._get_scaling_reason(load, action)
}
def _get_scaling_reason(self, load: dict, action: str) -> str:
"""获取扩缩容原因说明"""
if action == "scale_up":
reasons = []
if load['cpu_percent'] > 80:
reasons.append(f"CPU使用率过高({load['cpu_percent']}%)")
if load['memory_percent'] > 80:
reasons.append(f"内存使用率过高({load['memory_percent']}%)")
return ",".join(reasons)
elif action == "scale_down":
return "系统负载较低,可适当减少资源占用"
else:
return "系统负载正常,无需调整"
def print_optimization_report(self):
"""打印优化建议报告"""
print("\n" + "="*60)
print("📊 系统资源优化建议报告")
print("="*60)
load = self.get_system_load()
print(f"💻 CPU使用率: {load['cpu_percent']}%")
print(f"🧠 内存使用率: {load['memory_percent']}%")
print(f"💾 磁盘使用率: {load['disk_percent']:.2f}%")
print("\n💡 优化建议:")
if load['cpu_percent'] > 80:
print(" ⚠️ CPU使用率过高,建议:")
print(" 1. 增加Worker服务副本数")
print(" 2. 优化AI模型推理代码")
print(" 3. 考虑使用更强大的硬件")
if load['memory_percent'] > 80:
print(" ⚠️ 内存使用率过高,建议:")
print(" 1. 调整容器内存限制")
print(" 2. 优化数据处理逻辑,及时释放内存")
print(" 3. 考虑使用内存数据库")
if load['disk_percent'] > 80:
print(" ⚠️ 磁盘使用率过高,建议:")
print(" 1. 清理不必要的日志文件")
print(" 2. 配置日志轮转")
print(" 3. 移除不需要的Docker镜像")
if all(value < 30 for value in [load['cpu_percent'], load['memory_percent'], load['disk_percent']]):
print(" ✅ 系统资源使用正常,无需特别优化")
def main():
"""主函数"""
optimizer = ResourceOptimizer()
optimizer.print_optimization_report()
if __name__ == "__main__":
main()
11.2 扩展性优化
通过以下方式提高系统的扩展性:
- 水平扩展:使用–scale参数动态调整服务副本数
- 负载均衡:在多个副本前部署负载均衡器
- 微服务架构:将大型服务拆分为更小的独立服务
12. 安全最佳实践
12.1 镜像安全
# 使用官方基础镜像
FROM python:3.9-slim
# 以非root用户运行
RUN useradd --create-home --shell /bin/bash app
USER app
WORKDIR /home/app
# 只安装必要的依赖
COPY --chown=app:app requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY --chown=app:app . .
# 暴露必要的端口
EXPOSE 8000
# 启动应用
CMD ["python", "app.py"]
12.2 网络安全
# 限制外部访问
services:
redis:
ports:
- "127.0.0.1:6381:6381" # 仅本地访问
networks:
- backend
api:
ports:
- "8083:8083" # 对外提供服务
networks:
- backend
12.3 配置安全
# 不在配置文件中硬编码敏感信息
# 使用环境变量或Docker secrets
DATABASE_URL=${DATABASE_URL}
API_KEY=${API_KEY}
SECRET_KEY=${SECRET_KEY}
13. 扩展阅读
- Docker Compose官方文档: https://docs.docker.com/compose/
- Docker最佳实践: https://docs.docker.com/develop/develop-images/dockerfile_best_practices/
- Playwright官方文档: https://playwright.dev/
- Redis官方文档: https://redis.io/documentation/
- Python Docker SDK文档: https://docker-py.readthedocs.io/
14. 项目实施计划
15. 资源分配情况

总结
本文详细介绍了如何使用Docker Compose构建和部署一个完整的AI应用系统。通过实践案例,我们展示了从环境搭建、服务配置到监控管理的全过程,并提供了丰富的代码示例和最佳实践建议。
关键要点总结:
- 合理规划架构:采用微服务架构,将复杂系统拆分为独立的服务组件
- 配置资源限制:根据服务特性合理分配CPU和内存资源
- 实施健康检查:确保服务稳定运行,及时发现和处理问题
- 建立监控机制:通过Python脚本实时监控服务状态和资源使用情况
- 关注安全实践:从镜像安全、网络安全和配置安全多个维度保障系统安全
- 持续优化改进:根据系统负载动态调整资源配置,提高资源利用率
通过遵循这些最佳实践,AI应用开发者可以快速构建稳定、高效、可扩展的容器化应用系统。Docker Compose作为轻量级的容器编排工具,特别适合中小型AI项目的开发和部署,能够显著提高开发效率和系统可靠性。
236

被折叠的 条评论
为什么被折叠?



