MonkeyCode企业级内网部署完全手册:从零到生产(2026实战版)
"对于金融、政府、军工等安全敏感行业来说,'数据不出内网'不是可选项——而是硬性要求。MonkeyCode开源版的价值正在于此:它让你在内网隔离环境中也能拥有世界级的AI编程能力" —— 本文提供一份完整的企业级内网部署指南,涵盖从环境准备到生产运维的全流程。
一、为什么需要内网部署?
🔒 内网部署的必要性分析
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
必须内网部署的行业和场景:
┌─────────────────────────────────────────────┐
│ 🏦 金融行业(银行/证券/保险/支付) │
│ → 监管要求:等保三级、PCI-DSS │
│ → 数据合规:客户数据禁止出境 │
│ → 审计要求:所有操作可追溯 │
├─────────────────────────────────────────────┤
│ 🏛️ 政府/军工/央企 │
│ → 涉密信息系统分级保护 │
│ → 信创国产化要求 │
│ → 与互联网物理隔离 │
├─────────────────────────────────────────────┤
│ 🏥 医疗健康(医院/药企/医保) │
│ → HIPAA/GDPR等隐私法规 │
│ → 患者数据绝对保密 │
│ → 医疗器械软件认证 │
├─────────────────────────────────────────────┤
│ 🔬 科研院所(国防科研/前沿技术) │
│ → 知识产权保护 │
│ → 研究数据防泄露 │
│ → 专有算法不外泄 │
├─────────────────────────────────────────────┤
│ 🏭 大型制造业(汽车/航空/能源) │
│ → 工业控制系统安全 │
│ → 供应链知识产权保护 │
│ → 内部研发资产防护 │
└─────────────────────────────────────────────┘
内网部署 vs 云端使用对比:
维度 云端版 开源内网版
──────────────────────────────────────────────
数据位置 云端服务器 本地机房 ✅
网络要求 需要外网 完全离线可用 ✅
数据主权 供应商持有 自己掌控 ✅
合规审计 依赖供应商报告 自主可控 ✅
定制能力 受限 完全自由 ✅
成本模式 按用量付费 一次性投入 ✅
运维复杂度 低(托管) 中高(自维护)
功能完整性 100% 100%(同源码)
二、部署前准备
2.1 硬件需求评估
💻 硬件配置参考表
团队规模 推荐配置 CPU 内存 硬盘 带宽
─────────────────────────────────────────────────────────────
1-10人 最小可用 4核 8G 50G SSD 不需要
10-30人 推荐配置 8核 16G 200G SSD 不需要
30-100人 标准生产 16核 32G 500G SSD 局域网
100-500人 高性能配置 32核 64G 1T SSD 千兆+
500人+ 集群部署(见下文K8s方案) 多节点 多节点 共享存储 万兆
详细说明:
CPU:
→ 主要消耗在LLM API转发和代码分析上
→ AI模型推理不在本地(调用外部API),CPU压力不大
→ 推荐:Intel Xeon Gold 或 AMD EPYC 系列
内存:
→ PostgreSQL + Redis + 后端服务 占主要内存
→ 规则:每并发用户预留 512MB - 1GB
→ 示例:50人团队 → 32GB 足够
硬盘:
→ 代码仓库缓存:按项目数量估算(通常 10-50GB)
→ 扫描历史记录:建议保留3个月(20-100GB)
→ 日志文件:开启日志轮转后约 5-20GB
→ 总计:SSD 200GB 起,推荐 500GB+
网络:
→ 内网部署不需要公网IP
→ 但需要能够访问LLM Provider API(或本地模型)
→ 如果完全离线:需要额外部署本地大模型(见第七节)
💡 成本估算(一次性硬件投入):
30人团队标准配置 ≈ ¥3-5万(服务器+存储+网络设备)
对比云端方案年费 ≈ ¥5-10万/年
→ 内网部署第1年即可回本!
2.2 软件依赖清单
📦 必需软件清单
操作系统(选一):
├── Ubuntu Server 22.04 LTS / 24.04 LTS ← 推荐
├── CentOS Stream 9 / Rocky Linux 9
├── Debian 12 (Bookworm)
└── Red Hat Enterprise Linux 9(需订阅)
运行时环境:
├── Python 3.11+ (后端核心服务)
├── Node.js 18+ LTS (前端构建)
├── PostgreSQL 15+ (主数据库)
├── Redis 7+ (缓存/队列)
├── Git 2.40+ (版本控制集成)
└── Docker & Docker Compose(可选,容器化部署)
开发工具(可选但推荐):
├── GitLab CE / Gitea (代码托管)
├── Jenkins / GitLab CI (CI/CD集成)
├── Prometheus + Grafana (监控告警)
└── ELK Stack / Loki (日志收集)
LLM Provider(至少选一个):
├── DeepSeek API ← 性价比最高(推荐)
├── 通义千问 Qwen API ← 国内访问快
├── 智谱AI GLM API ← 国产可靠
├── 百度文心一言 ERNIE API
├── 本地部署模型(完全离线方案)
│ ├── Qwen2.5-Coder-7B-Instruct
│ ├── DeepSeek-Coder-V2-Lite
│ └── CodeLlama-70B(需要强GPU)
三、快速部署(Docker Compose方式)
# docker-compose.production.yaml — 生产级Docker编排
version: '3.8'
services:
# ════════════════════════════════
# PostgreSQL 数据库
# ════════════════════════════════
postgres:
image: postgres:15-alpine
container_name: mc-postgres
restart: unless-stopped
environment:
POSTGRES_DB: monkeycode
POSTGRES_USER: ${DB_USER:-mc_admin}
POSTGRES_PASSWORD: ${DB_PASSWORD:-CHANGE_ME_IN_PRODUCTION}
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- pg_data:/var/lib/postgresql/data
- ./init-db:/docker-entrypoint-initdb.d:ro
ports:
- "127.0.0.1:5432:5432" # 仅本地绑定
command:
- "postgres"
- "-c"
- "max_connections=200"
- "-c"
- "shared_buffers=256MB"
- "-c"
- "effective_cache_size=768MB"
- "-c"
- "maintenance_work_mem=64MB"
- "-c"
- "wal_level=replica"
- "-c"
- "max_wal_senders=3"
- "-c"
- "hot_standby=on"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U mc_admin -d monkeycode"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- mc-backend
logging:
driver: json-file
options:
max-size: "50m"
max-file: "3"
# ════════════════════════════════
# Redis 缓存
# ════════════════════════════════
redis:
image: redis:7-alpine
container_name: mc-redis
restart: unless-stopped
command: >
redis-server
--requirepass ${REDIS_PASSWORD:-CHANGE_ME}
--maxmemory 512mb
--maxmemory-policy allkeys-lru
--appendonly yes
--appendfsync everysec
--save 60 1000
--save 300 100
volumes:
- redis_data:/data
ports:
- "127.0.0.1:6379:6379" # 仅本地绑定
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-CHANGE_ME}", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- mc-backend
logging:
driver: json-file
options:
max-size: "20m"
max-file: "3"
# ════════════════════════════════
# MonkeyCode API 服务
# ════════════════════════════════
monkeycode-api:
build:
context: .
dockerfile: Dockerfile.api
args:
PYTHON_VERSION: "3.11"
image: monkeycode-api:latest
container_name: mc-api
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
# 数据库连接
DATABASE_URL: postgresql://mc_admin:${DB_PASSWORD:-CHANGE_ME}@postgres:5432/monkeycode
# Redis连接
REDIS_URL: redis://:${REDIS_PASSWORD:-CHANGE_ME}@redis:6379/0
# LLM Provider 配置
LLM_PROVIDER: ${LLM_PROVIDER:-deepseek}
DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}
QWEN_API_KEY: ${QWEN_API_KEY}
GLM_API_KEY: ${GLM_API_KEY}
# 应用配置
SECRET_KEY: ${SECRET_KEY:-generate-random-here}
ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-http://localhost:3000}
LOG_LEVEL: ${LOG_LEVEL:-INFO}
# 安全配置
ENABLE_AUTH: "true"
AUTH_METHOD: ${AUTH_METHOD:-ldap} # ldap/oauth2/token
LDAP_URL: ${LDAP_URL:-ldap://your-ldap-server:389}
LDAP_BASE_DN: ${LDAP_BASE_DN:-dc=company,dc=com}
LDAP_BIND_USER: ${LDAP_BIND_USER}
LDAP_BIND_PASSWORD: ${LDAP_BIND_PASSWORD}
# SDD默认配置
SDD_DEFAULT_PATH: /app/config/default.sdd.yaml
# MonkeyScan配置
MONKEYSCAN_ENABLED: "true"
MONKEYSCAN_BLOCK_ON_CRITICAL: "true"
# Worker配置
WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-4}
TASK_TIMEOUT: ${TASK_TIMEOUT:-1800} # 30分钟超时
ports:
- "8000:8000"
volumes:
- ./config:/app/config:ro # 只读挂载配置
- workspace_data:/app/workspace # 工作区数据
- scan_reports:/app/reports # 扫描报告
- logs:/app/logs # 日志目录
networks:
- mc-backend
- mc-frontend
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
cpus: '4.0'
memory: 4G
reservations:
cpus: '2.0'
memory: 2G
logging:
driver: json-file
options:
max-size: "100m"
max-file: "5"
# ════════════════════════════════
# MonkeyCode Web 前端
# ════════════════════════════════
monkeycode-web:
build:
context: .
dockerfile: Dockerfile.web
args:
NODE_ENV: production
VITE_API_BASE_URL: http://${HOST_IP:-localhost}:8000
image: monkeycode-web:latest
container_name: mc-web
restart: unless-stopped
depends_on:
- monkeycode-api
ports:
- "3000:80" # Nginx在容器内监听80
networks:
- mc-frontend
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
logging:
driver: json-file
options:
max-size: "20m"
max-file: "3"
# ════════════════════════════════
# Nginx 反向代理(可选,用于生产环境)
# ════════════════════════════════
nginx:
image: nginx:alpine
container_name: mc-nginx
restart: unless-stopped
depends_on:
- monkeycode-api
- monkeycode-web
ports:
- "443:443"
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/certs:/etc/nginx/certs:ro # SSL证书
- nginx_logs:/var/log/nginx
networks:
- mc-frontend
- mc-backend
logging:
driver: json-file
options:
max-size: "20m"
max-file: "3"
# ════════════════════════════════════
# 数据卷定义
# ════════════════════════════════════
volumes:
pg_data:
driver: local
redis_data:
driver: local
workspace_data:
driver: local
scan_reports:
driver: local
logs:
driver: local
nginx_logs:
driver: local
# ════════════════════════════════════
# 网络定义
# ════════════════════════════════════
networks:
mc-backend:
driver: bridge
internal: true # 内部网络,不暴露到宿主机
mc-frontend:
driver: bridge
四、Nginx反向代理与SSL配置
# nginx/nginx.conf — 生产级Nginx配置
# 全局设置
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 2048;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# 基础优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript
application/xml application/rss+xml image/svg+xml;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# 上传大小限制(代码文件可能较大)
client_max_body_size 50m;
# 速率限制
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# HTTP → HTTPS 重定向
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
server {
listen 80;
server_name monkeycode.yourcompany.com;
# ACME证书挑战(Let's Encrypt)
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# 其他请求重定向到HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# HTTPS 主站配置
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
server {
listen 443 ssl http2;
server_name monkeycode.yourcompany.com;
# SSL证书配置
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# HSTS(严格传输安全)
add_header Strict-Transport-Security "max-age=63072000" always;
# 前端静态资源
location / {
proxy_pass http://monkeycode-web:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket支持(实时通知)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# API代理
location /api/ {
limit_req zone=api_limit burst=50 nodelay;
proxy_pass http://monkeycode-api:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# API超时设置(长时间任务)
proxy_connect_timeout 60s;
proxy_read_timeout 1800s; # 30分钟(Agent任务可能很长)
proxy_send_timeout 60s;
# 缓冲设置
proxy_buffering off; # 流式响应
}
# 登录接口特殊限制(防暴力破解)
location = /api/auth/login {
limit_req zone=login_limit burst=3 nodelay;
proxy_pass http://monkeycode-api:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 健康检查端点(无需认证)
location /health {
proxy_pass http://monkeycode-api:8000;
access_log off;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
proxy_pass http->monkeycode-web:80;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
}
五、LDAP/AD域认证集成
# config/auth_ldap.py — LDAP认证配置示例
"""
MonkeyCode LDAP/Active Directory 认证集成
支持两种模式:
1. LDAP Simple Bind(简单绑定)
2. Active Directory Kerberos认证(高级安全)
"""
import os
from dataclasses import dataclass
from typing import Optional, List
@dataclass
class LDAPConfig:
"""LDAP配置"""
server_url: str # ldap://ad.company.com:389
base_dn: str # dc=company,dc=com
bind_user: str # cn=admin,dc=company,dc=com
bind_password: str
user_search_base: str # ou=Users,dc=company,dc=com
group_search_base: str # ou=Groups,dc=company,dc=com
# 用户属性映射
username_attr: str = "sAMAccountName" # AD用sAMAccountName
email_attr: str = "mail"
display_name_attr: str = "displayName"
# 组权限映射
admin_group_dn: Optional[str] = None # cn=MC-Admins,ou=Groups,...
developer_group_dn: Optional[str] = None
viewer_group_dn: Optional[str] = None
# 安全选项
use_ssl: bool = True
cert_path: Optional[str] = None
# 默认配置模板
DEFAULT_LDAP_CONFIG = LDAPConfig(
server_url=os.getenv("LDAP_URL", "ldap://ad.company.com:389"),
base_dn=os.getenv("LDAP_BASE_DN", "dc=company,dc=com"),
bind_user=os.getenv("LDAP_BIND_USER", ""),
bind_password=os.getenv("LDAP_BIND_PASSWORD", ""),
user_search_base=os.getenv("LDAP_USER_BASE", "ou=Developers,dc=company,dc=com"),
group_search_base=os.getenv("LDAP_GROUP_BASE", "ou=Groups,dc=company,dc=com"),
admin_group_dn="cn=MonkeyCode-Admins,ou=Groups,dc=company,dc=com",
developer_group_dn="cn=MonkeyCode-Users,ou=Groups,dc=company,dc=com",
viewer_group_dn="cn=MonkeyCode-Viewers,ou=Groups,dc=company,dc=com",
use_ssl=True,
)
# 使用说明:
# 1. 在 .env 文件中配置LDAP连接信息
# 2. 确保MonkeyCode服务器能访问LDAP服务器端口(389/636)
# 3. 在AD中创建对应的用户组
# 4. 将用户分配到对应组以获得相应权限
# 权限体系:
# MC-Admins组 → 管理员(全部权限 + 系统管理)
# MC-Users组 → 普通开发者(使用AI编程 + 查看自己的项目)
# MC-Viewers组 → 只读用户(仅查看扫描报告和统计)
六、备份与灾难恢复
#!/bin/bash
# scripts/backup.sh — 自动化备份脚本
set -euo pipefail
# ═════════════════════════════════════════
# MonkeyCode 企业级备份脚本
# 建议:通过cron每天凌晨2点执行
# crontab: 0 2 * * * /opt/monkeycode/scripts/backup.sh
# ═════════════════════════════════════════
CONFIG_DIR="/opt/monkeycode/config"
BACKUP_ROOT="/opt/monkeycode/backups"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="${BACKUP_ROOT}/${DATE}"
RETENTION_DAYS=30 # 保留30天备份
echo "[${DATE}] 开始备份..."
# 创建备份目录
mkdir -p "${BACKUP_DIR}/{db,config,workspace,reports}"
# ═════════════════════════════════════════
# 1. PostgreSQL 数据库备份
# ═════════════════════════════════════════
echo ">>> 备份数据库..."
docker exec mc-postgres pg_dump \
-U mc_admin \
-F c \
-f "/backups/db/monkeycode_${DATE}.dump" \
monkeycode
echo " 数据库备份完成: $(du -h ${BACKUP_DIR}/db/*.dump | cut -f1)"
# ═════════════════════════════════════════
# 2. 配置文件备份
# ═════════════════════════════════════════
echo ">>> 备份配置文件..."
cp -r "${CONFIG_DIR}/" "${BACKUP_DIR}/config/"
# 敏感信息脱敏(移除真实密码)
find "${BACKUP_DIR}/config" -name ".env" -exec sed -i 's/PASSWORD=.*/PASSWORD=**REDACTED**/' {} \;
echo " 配置文件备份完成"
# ═════════════════════════════════════════
# 3. 工作区数据备份(增量)
# ═════════════════════════════════════════
echo ">>> 备份工作区数据..."
docker cp mc-api:/app/workspace "${BACKUP_DIR}/workspace/"
echo " 工作区备份完成: $(du -sh ${BACKUP_DIR}/workspace | cut -f1)"
# ═════════════════════════════════════════
# 4. 扫描报告备份
# ═════════════════════════════════════════
echo ">>> 备份扫描报告..."
docker cp mc-api:/app/reports "${BACKUP_DIR}/reports/"
echo " 报告备份完成: $(du -sh ${BACKUP_DIR}/reports | cut -f1)"
# ═════════════════════════════════════════
# 5. 压缩打包
# ═════════════════════════════════════════
echo ">>> 压缩备份..."
tar -czf "${BACKUP_ROOT}/monkeycode_backup_${DATE}.tar.gz" \
-C "${BACKUP_ROOT}" "${DATE}"
# 清理未压缩目录
rm -rf "${BACKUP_DIR}"
BACKUP_SIZE=$(du -h "${BACKUP_ROOT}/monkeycode_backup_${DATE}.tar.gz" | cut -f1)
echo " 备份包大小: ${BACKUP_SIZE}"
# ═════════════════════════════════════════
# 6. 清理过期备份
# ═════════════════════════════════════════
echo ">>> 清理${RETENTION_DAYS}天前的旧备份..."
find "${BACKUP_ROOT}" -name "*.tar.gz" -mtime +${RETENTION_DAYS} -delete
TOTAL_SIZE=$(du -sh ${BACKUP_ROOT} | cut -f1)
echo " 备份总占用空间: ${TOTAL_SIZE}"
# ═════════════════════════════════════════
# 7. 备份验证(可选)
# ═════════════════════════════════════════
echo ">>> 验证备份完整性..."
if tar -tzf "${BACKUP_ROOT}/monkeycode_backup_${DATE}.tar.gz" >/dev/null 2>&1; then
echo " ✅ 备份验证通过"
else
echo " ❌ 备份损坏!请检查磁盘空间"
exit 1
fi
echo "[${DATE}] 备份完成!✅"
echo "备份文件: ${BACKUP_ROOT}/monkeycode_backup_${DATE}.tar.gz"
七、完全离线方案(本地大模型部署)
🔒 完全离线部署架构图
当企业网络无法访问任何外部API时,
需要在内部部署本地大语言模型。
┌─────────────────────────────────────────────────────┐
│ 完全离线架构 │
│ │
│ ┌──────────┐ │
│ │ GPU服务器 │ ← 需要 NVIDIA A100/H100 或等效GPU │
│ │ (推理节点)│ │
│ └────┬─────┘ │
│ │ vLLM / TGI 推理引擎 │
│ │ │
│ ┌────▼──────────────────────────────────────┐ │
│ │ 本地模型选择 │ │
│ ├─────────────────────────────────────────────┤ │
│ │ 模型 │ 显存需求 │ 推荐GPU │ │
│ ├──────────────────┼─────────┼───────────────┤ │
│ │ Qwen2.5-Coder-7B │ 16GB │ RTX 4090/A5000│ │
│ │ Qwen2.5-Coder-32B │ 72GB │ A100 80GB×1 │ │
│ │ DeepSeek-V2-Lite │ 48GB │ A6000×2 │ │
│ │ CodeLlama-70B │ 140GB │ A100 80GB×2 │ │
│ │ Qwen2.5-Coder-72B │ 144GB │ H100 80GB×2 │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ MonkeyCode配置修改: │
│ LLM_PROVIDER=vllm │
│ VLLM_ENDPOINT=http://gpu-server:8000/v1 │
│ │
│ 所有数据流: │
│ 用户 → MonkeyCode → 本地模型 → 结果 │
│ ↑ 全程不出内网 ↑ │
└─────────────────────────────────────────────────────┘
vLLM部署命令示例(Qwen2.5-Coder-7B):
# 在GPU服务器上执行
pip install vllm
# 启动推理服务
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-Coder-7B-Instruct \
--tensor-parallel-size 1 \
--max-model-len 32768 \
--gpu-memory-utilization 0.9 \
--port 8000 \
--host 0.0.0.0
# MonkeyCode .env 配置
LLM_PROVIDER=openai-compatible
OPENAI_API_BASE_URL=http://gpu-server:8000/v1
OPENAI_API_KEY=not-needed-for-local
💡 性能参考(单卡A100):
Qwen2.5-Coder-7B:
→ 首token延迟: <1秒
→ 生成速度: 50-80 tokens/s
→ 并发支持: 4-8个同时请求
→ 代码质量: 接近GPT-4水平(编码任务)
足够支撑20-50人的团队日常使用!
八、监控与运维
📊 运维监控体系
关键监控指标:
┌──────────────────────────────────────────────────┐
│ 类别 │ 指标 │ 告警阈值 │
├────────────┼───────────────────┼────────────────┤
│ 可用性 │ 服务健康状态 │ != UP 时告警 │
│ │ HTTP响应时间(P99) │ > 5s 告警 │
│ │ 错误率(5xx) │ > 1% 告警 │
├────────────┼───────────────────┼────────────────┤
│ 性能 │ API QPS │ > 1000 时关注 │
│ │ Agent任务排队长度 │ > 10 告警 │
│ │ LLM响应延迟(P95) │ > 30s 告警 │
│ │ 数据库查询时间P99 │ > 500ms 告警 │
├────────────┼───────────────────┼────────────────┤
│ 资源 │ CPU使用率 │ > 85% 告警 │
│ │ 内存使用率 │ > 90% 告警 │
│ │ 磁盘使用率 │ > 85% 告警 │
│ │ Redis内存使用率 │ > 80% 告警 │
├────────────┼───────────────────┼────────────────┤
│ 业务 │ 日活用户数(DAU) │ 异常下降告警 │
│ │ Agent任务成功率 │ < 95% 告警 │
│ │ 安全漏洞发现数 │ Critical>0告警│
│ │ Token日消耗量 │ 异常激增告警 │
└────────────┴───────────────────┴────────────────┘
推荐监控栈:
Prometheus(指标采集)+ Grafana(可视化展示)
+ AlertManager(告警通知)
+ PagerDuty/钉钉/企微(告警通道)
九、常见问题排查
🔧 故障排查速查表
问题1:服务启动失败,报数据库连接错误
→ 检查PostgreSQL是否正常运行:docker ps | grep postgres
→ 检查连接字符串是否正确:用户名/密码/主机名
→ 检查防火墙是否放行5432端口(容器间通信)
→ 查看日志:docker logs mc-postgres
问题2:前端页面加载空白
→ 检查API服务是否启动:curl localhost:8000/health
→ 检查CORS配置:ALLOWED_ORIGINS是否包含前端地址
→ 检查Nginx配置:proxy_pass目标是否正确
→ 浏览器F12查看Console错误信息
问题3:AI功能无响应或报错
→ 检查LLM API Key是否正确配置
→ 测试API连通性:curl -X POST {provider_url}/chat/completions
→ 检查Token余额(DeepSeek/通义等平台控制台)
→ 查看API调用日志:docker logs mc-api | grep llm
问题4:MonkeyScan扫描结果全为空
→ 检查MONKEYSCAN_ENABLED=true是否设置
→ 确认.sdd.yaml中的security_rules配置存在
→ 检查扫描器规则文件是否加载成功
→ 手动触发一次扫描测试
问题5:LDAP认证失败
→ 测试LDAP连通性:ldapsearch -x -H ldap://server:389
→ 检查bind_user是否有足够的搜索权限
→ 确认base_dn和user_search_base路径正确
→ 检查SSL证书(如果use_ssl=true)
问题6:性能随时间下降
→ 检查PostgreSQL表是否需要VACUUM ANALYZE
→ 检查Redis内存是否达到上限
→ 查看工作区目录大小(可能需要清理)
→ 检查Docker容器日志大小
十、部署检查清单
✅ 生产部署最终检查清单
□ 环境准备
□ 操作系统已更新至最新补丁
□ Docker和Docker Compose已安装
□ 防火墙规则已配置(仅开放必要端口)
□ DNS解析已配置(如使用域名)
□ SSL证书已获取并部署
□ 安全加固
□ 所有密码已从默认值更改
□ .env文件权限设为600
□ LDAP/AD认证已配置并测试
□ HTTPS已启用
□ 安全头已配置(Nginx)
□ 数据库仅允许本地访问
□ 功能验证
□ 用户登录/登出正常
□ AI代码生成功能正常
□ SDD规范加载正常
□ MonkeyScan扫描正常
□ Git集成正常
□ Agent任务执行正常
□ 高可用(可选)
□ PostgreSQL主从复制已配置
□ Redis持久化(AOF)已启用
□ Docker重启策略为unless-stopped
□ 定期备份脚本已配置cron
□ 监控告警已配置
□ 文档移交
□ 架构拓扑图已绘制
□ 管理员账号信息已记录
□ 备份恢复步骤已文档化
□ 应急联系人列表已建立
□ 运维手册已编写完成
📌 总结
MonkeyCode的内网部署并不复杂——它本质上是一个标准的Python Web应用加上一些AI相关的组件。Docker Compose方式可以在30分钟内完成基础部署,而Kubernetes集群方案则可以支撑千人规模的团队。最关键的是:一旦部署完成,你的团队就拥有了一个与世界级AI编程能力完全对等的、数据完全自主可控的研发工具。而且这一切,基于AGPL-3.0协议永久免费。
🔗 系列导航
- 上一篇:《MonkeyScan安全扫描引擎:开源版的代码安全守护者》
- [第5篇/共30篇]
- [下一篇:《MonkeyCode MCP协议集成:打造开放的AI工具生态》]
本文为MonkeyCode开源系列第5篇,基于实际生产环境部署经验撰写。
浙公网安备 33010602011771号