基于Docker Compose的AI应用开发与部署实践完整指南

部署运行你感兴趣的模型镜像

摘要

随着人工智能技术的迅猛发展,越来越多的应用需要集成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核心概念
  1. 服务(Service):一个应用容器,实际上就是Docker镜像的一个运行实例
  2. 项目(Project):由一组关联的应用容器组成的一个完整业务单元
  3. 卷(Volume):用于持久化数据的机制
  4. 网络(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应用系统的整体架构如下图所示:

客户端/用户
API服务
Redis缓存/队列
Playwright服务
Worker服务
数据存储
网页数据
5.2 各组件功能说明
  1. API服务:提供RESTful API接口,接收客户端请求并返回处理结果
  2. Worker服务:处理耗时的后台任务,如网页爬取、数据处理等
  3. Playwright服务:专门用于网页自动化操作,处理JavaScript渲染的页面
  4. 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搭建一个包含以下组件的系统:

  1. API服务:提供RESTful接口接收用户请求
  2. Worker服务:处理后台爬取和分析任务
  3. Playwright服务:处理复杂的网页交互
  4. Redis服务:作为任务队列和缓存
7.2 实施步骤
  1. 项目初始化
# 创建项目目录
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
  1. 编写Docker Compose文件

参考第4节的配置文件内容。

  1. 配置环境变量

参考第4.2节的环境变量配置。

  1. 启动系统
# 启动所有服务
docker-compose -p ai-analyzer up -d

# 查看服务状态
docker-compose -p ai-analyzer ps

# 查看服务日志
docker-compose -p ai-analyzer logs -f
  1. 验证系统功能
# 测试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 服务启动失败

问题现象:服务容器启动后立即退出

解决方案

  1. 检查日志:docker-compose logs service-name
  2. 验证配置:docker-compose config
  3. 检查端口冲突:确保端口未被占用
10.2 网络连接问题

问题现象:服务间无法通信

解决方案

  1. 检查网络配置:确保服务在同一网络中
  2. 验证服务名称解析:使用服务名称而非IP地址
  3. 检查防火墙设置:确保端口开放
10.3 资源不足

问题现象:容器被系统终止或性能下降

解决方案

  1. 增加资源限制:调整memory和cpus配置
  2. 优化应用代码:减少内存使用和CPU消耗
  3. 扩展服务副本:使用–scale参数增加副本数
10.4 数据持久化问题

问题现象:容器重启后数据丢失

解决方案

  1. 配置卷映射:将重要数据存储在卷中
  2. 定期备份:建立数据备份机制
  3. 使用外部存储:对于重要数据使用外部数据库

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 扩展性优化

通过以下方式提高系统的扩展性:

  1. 水平扩展:使用–scale参数动态调整服务副本数
  2. 负载均衡:在多个副本前部署负载均衡器
  3. 微服务架构:将大型服务拆分为更小的独立服务

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. 扩展阅读

  1. Docker Compose官方文档: https://docs.docker.com/compose/
  2. Docker最佳实践: https://docs.docker.com/develop/develop-images/dockerfile_best_practices/
  3. Playwright官方文档: https://playwright.dev/
  4. Redis官方文档: https://redis.io/documentation/
  5. Python Docker SDK文档: https://docker-py.readthedocs.io/

14. 项目实施计划

2025-09-07 2025-09-14 2025-09-21 2025-09-28 2025-10-05 2025-10-12 2025-10-19 需求分析 技术选型 环境搭建 Docker Compose配置 服务开发 单元测试 集成测试 性能测试 安全测试 生产环境部署 监控系统搭建 文档编写 项目准备 开发阶段 测试阶段 部署阶段 AI应用Docker Compose部署项目计划

15. 资源分配情况

在这里插入图片描述

总结

本文详细介绍了如何使用Docker Compose构建和部署一个完整的AI应用系统。通过实践案例,我们展示了从环境搭建、服务配置到监控管理的全过程,并提供了丰富的代码示例和最佳实践建议。

关键要点总结:

  1. 合理规划架构:采用微服务架构,将复杂系统拆分为独立的服务组件
  2. 配置资源限制:根据服务特性合理分配CPU和内存资源
  3. 实施健康检查:确保服务稳定运行,及时发现和处理问题
  4. 建立监控机制:通过Python脚本实时监控服务状态和资源使用情况
  5. 关注安全实践:从镜像安全、网络安全和配置安全多个维度保障系统安全
  6. 持续优化改进:根据系统负载动态调整资源配置,提高资源利用率

通过遵循这些最佳实践,AI应用开发者可以快速构建稳定、高效、可扩展的容器化应用系统。Docker Compose作为轻量级的容器编排工具,特别适合中小型AI项目的开发和部署,能够显著提高开发效率和系统可靠性。

参考资料

  1. Docker Compose官方文档
  2. Docker最佳实践指南
  3. Playwright官方文档
  4. Redis官方文档
  5. Python Docker SDK文档
  6. 容器化AI应用部署最佳实践

您可能感兴趣的与本文相关的镜像

ComfyUI

ComfyUI

AI应用
ComfyUI

ComfyUI是一款易于上手的工作流设计工具,具有以下特点:基于工作流节点设计,可视化工作流搭建,快速切换工作流,对显存占用小,速度快,支持多种插件,如ADetailer、Controlnet和AnimateDIFF等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CarlowZJ

我的文章对你有用的话,可以支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值