services:
frontend:
image: ${DOCKER_REGISTRY}/agent-platform-front:${FRONTEND_VERSION}
ports:
- "${FRONTEND_HOST_PORT}:80"
volumes:
- ./config/nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./app/front:/app/nginx/html:ro
- ./upload:/app/upload
depends_on:
backend:
condition: service_healthy
environment:
- NODE_ENV=production
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/index.html"]
interval: 10s
timeout: 5s
retries: 3
start_period: 10s
networks:
- agent-network
backend:
image: ${DOCKER_REGISTRY}/agent-platform-backend:${BACKEND_VERSION}
ports:
- "8080:${APP_PORT}"
- "5005:${APP_DEBUG_PORT}"
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
milvus:
condition: service_healthy
environment:
- JAVA_OPTS=-server -Xms2024m -Xmx2024m -XX:MaxMetaspaceSize=256m -XX:MaxMetaspaceFreeRatio=70
- APP_PROFILE=${APP_PROFILE}
- APP_PORT=${APP_PORT}
- APP_DEBUG_PORT=${APP_DEBUG_PORT}
- ENABLE_DEBUG=false
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
- MILVUS_HOST=${MILVUS_HOST}
- MILVUS_PORT=${MILVUS_PORT}
- MILVUS_URI=${MILVUS_URI}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_PORT=${MYSQL_PORT}
- DORIS_HOST=${DORIS_HOST}
- DORIS_PORT=${DORIS_PORT}
- DORIS_USER=${DORIS_USER}
- DORIS_PASSWORD=${DORIS_PASSWORD}
- DORIS_DB=${DORIS_DB}
- DORIS_ROOT_USERNAME=${DORIS_ROOT_USERNAME}
volumes:
- ./app/app.jar:/app/app.jar:ro
- ./config/docker-entrypoint.sh:/docker-entrypoint.sh:ro
- ./config/application-external.yml:/app/config/application-external.yml:ro
- ./logs/agent:/app/logs
- ./upload:/app/upload
- ./data/jwt/:/app/config/jwt
entrypoint: ["/bin/bash", "-c", "/docker-entrypoint.sh 2>&1 | tee -a /app/logs/start.log"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:${APP_PORT}/ready"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: always
networks:
- agent-network
mcp-proxy:
image: ${DOCKER_REGISTRY}/mcp-proxy:${MCP_PROXY_VERSION}
ports:
- "8020:8089"
volumes:
- ./logs/mcp_proxy:/app/logs
- ./config/mcp_config.yml:/app/config.yml:ro
- ./data/uv_cache/uv:/root/.cache/uv
- ./data/npx_cache/.npm:/root/.npm
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8089/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
restart: always
networks:
- agent-network
mysql-permission-fix:
image: busybox:1.36-uclibc labels:
- "com.docker.compose.project=mysql-permission-fix"
- "description=MySQL权限修复初始化容器"
deploy:
resources:
limits:
cpus: '0.1'
memory: 32M
reservations:
cpus: '0.05'
memory: 16M
environment:
- MYSQL_UID=${MYSQL_UID:-999}
- MYSQL_GID=${MYSQL_GID:-999}
volumes:
- ./data/mysql:/var/lib/mysql
- ./logs/mysql:/var/log/mysql
- ./config/mysql.cnf:/tmp/mysql.cnf:rw command: |
sh -c "
set -e
echo '🔧 开始修复MySQL权限问题...'
echo '📋 当前用户: '$$(id)
echo '🔧 目标MySQL用户: ${MYSQL_UID:-999}:${MYSQL_GID:-999}'
# 创建必要目录
echo '📁 创建必要目录...'
mkdir -p /var/lib/mysql /var/log/mysql
# 设置数据目录权限给mysql用户(999)
echo '🔑 设置数据目录权限...'
chown -R ${MYSQL_UID:-999}:${MYSQL_GID:-999} /var/lib/mysql /var/log/mysql
chmod -R 755 /var/lib/mysql /var/log/mysql
# 检查和修复配置文件权限
echo '🔒 检查配置文件权限...'
if [ -f '/tmp/mysql.cnf' ]; then
CURRENT_PERM=\$$(stat -c '%a' /tmp/mysql.cnf 2>/dev/null || stat -f '%Lp' /tmp/mysql.cnf 2>/dev/null)
echo '📄 当前配置文件权限: '\$${CURRENT_PERM}
# 检查是否为组写入或全局写入权限(会被MySQL忽略)
if [ \"\$${CURRENT_PERM}\" = '775' ] || [ \"\$${CURRENT_PERM}\" = '777' ] || [ \"\$${CURRENT_PERM}\" = '664' ]; then
echo '⚠️ 配置文件权限不安全,MySQL会忽略此配置文件'
echo '🔧 修复配置文件权限为644...'
chmod 644 /tmp/mysql.cnf
echo '✅ 配置文件权限已修复为644'
else
echo '✅ 配置文件权限正常'
fi
# 显示修复后的权限
FIXED_PERM=\$$(stat -c '%a' /tmp/mysql.cnf 2>/dev/null || stat -f '%Lp' /tmp/mysql.cnf 2>/dev/null)
echo '📄 修复后配置文件权限: '\$${FIXED_PERM}
else
echo '⚠️ 配置文件 /tmp/mysql.cnf 不存在'
fi
# 验证权限设置
echo '🔍 验证权限设置...'
echo '📁 MySQL数据目录: '$$(ls -ld /var/lib/mysql)
echo '📁 MySQL日志目录: '$$(ls -ld /var/log/mysql)
# 检查现有数据
if [ -n \"$$(find /var/lib/mysql -name '*.ibd' -o -name '*.MYD' -o -name '*.MYI' 2>/dev/null)\" ]; then
echo '📊 检测到现有MySQL数据文件,权限已修复'
else
echo '📭 未检测到现有数据文件,这是首次初始化'
fi
echo '✅ MySQL权限修复完成'
echo '🎯 摘要:'
echo ' • 数据目录: /var/lib/mysql (755, ${MYSQL_UID:-999}:${MYSQL_GID:-999})'
echo ' • 日志目录: /var/log/mysql (755, ${MYSQL_UID:-999}:${MYSQL_GID:-999})'
echo ' • 配置文件: mysql.cnf (644, 安全权限)'
"
restart: "no"
networks:
- agent-network
mysql:
image: mysql:8.0
depends_on:
mysql-permission-fix:
condition: service_completed_successfully
ports:
- "13306:3306"
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- TZ=Asia/Shanghai
- MYSQL_CHARSET=utf8mb4
- MYSQL_COLLATION=utf8mb4_unicode_ci
volumes:
- ./data/mysql:/var/lib/mysql
- ./config/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
- ./config/init_mysql.sql:/docker-entrypoint-initdb.d/1_init_mysql.sql:ro
- ./config/init_mysql_data.sql:/docker-entrypoint-initdb.d/2_init_mysql_data.sql:ro
- ./logs/mysql:/var/log/mysql
command: >
--authentication-policy=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--init-connect='SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; SET character_set_client=utf8mb4; SET character_set_connection=utf8mb4; SET character_set_results=utf8mb4;'
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
restart: always
networks:
- agent-network
redis:
image: redis:7.0
ports:
- "16379:6379"
environment:
- TZ=Asia/Shanghai
command: redis-server /usr/local/etc/redis/redis.conf --port 6379 --requirepass 123456
volumes:
- ./data/redis:/data
- ./config/redis.conf:/usr/local/etc/redis/redis.conf:ro
- ./logs/redis:/data/logs/redis
healthcheck:
test: ["CMD", "redis-cli", "-p", "6379", "ping"]
interval: 10s
timeout: 5s
retries: 5
restart: always
networks:
- agent-network
milvus:
image: milvusdb/milvus:v2.5.8
ports:
- "19530:19530"
- "9091:9091"
- "2379:2379"
environment:
- TZ=Asia/Shanghai
- ETCD_USE_EMBED=true
- ETCD_DATA_DIR=/var/lib/milvus/etcd
- ETCD_CONFIG_PATH=/milvus/configs/embedEtcd.yaml
- COMMON_STORAGETYPE=local
- TIMEZONE=Asia/Shanghai
- LOG_LEVEL=error
- MILVUS_LOG_LEVEL=error
- LOG_STDOUT=false
- LOG_FILE_ROOTPATH=/var/log/milvus
volumes:
- ./data/milvus/data:/var/lib/milvus/data
- ./data/milvus/etcd:/var/lib/milvus/etcd
- ./config/milvus/embedEtcd.yaml:/milvus/configs/embedEtcd.yaml:ro
- ./config/milvus/user.yaml:/milvus/configs/user.yaml:ro
- ./config/milvus/milvus.yaml:/milvus/configs/milvus.yaml:ro
- ./logs/milvus:/var/log/milvus
command: ["milvus", "run", "standalone"]
security_opt:
- seccomp:unconfined
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
interval: 30s
timeout: 20s
retries: 3
start_period: 90s
restart: always
networks:
- agent-network
minio:
image: minio/minio:latest
ports:
- "9000:9000" - "9001:9001" volumes:
- ./data/minio:/data environment:
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
- TZ=Asia/Shanghai
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
restart: always
networks:
- agent-network
minio-init:
image: minio/mc
depends_on:
minio:
condition: service_healthy
entrypoint: >
/bin/sh -c "
chmod +x /scripts/init-minio.sh &&
/scripts/init-minio.sh
"
volumes:
- ./script:/scripts environment:
- MINIO_SERVER_URL=http://minio:9000
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
- MINIO_BUCKET_NAME=quickwit-indexes networks:
- agent-network
restart: "no"
log_platform:
image: ${DOCKER_REGISTRY}/log-platform:${LOG_PLATFORM_VERSION}
ports:
- "${LOG_PLATFORM_HOST_PORT:-8097}:8097"
volumes:
- ./logs/log_platform:/app/logs
- ./config/log_platform_config.yml:/app/config.yml:ro
environment:
- TZ=Asia/Shanghai
depends_on:
quickwit:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8097/health"] interval: 30s
timeout: 10s
retries: 3
start_period: 30s restart: always
networks:
- agent-network
quickwit:
image: quickwit/quickwit:latest
ports:
- "7280:7280"
- "7281:7281"
depends_on:
minio:
condition: service_healthy
environment:
- TZ=Asia/Shanghai
- QW_S3_ENDPOINT=http://minio:9000
- AWS_ACCESS_KEY_ID=${MINIO_ROOT_USER} - AWS_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD} - QW_S3_FLAVOR=minio
- AWS_REGION=us-east-1 - QW_S3_FORCE_PATH_STYLE_ACCESS=true
- QW_METASTORE_URI=s3://quickwit-indexes
- QW_DEFAULT_INDEX_ROOT_URI=s3://quickwit-indexes/ volumes:
- ./data/quickwit:/quickwit/qwdata - ./logs/quickwit:/quickwit/logs
command: ["run"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7280/api/v1/version"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
restart: always
networks:
- agent-network
networks:
agent-network:
driver: bridge
driver_opts:
com.docker.network.bridge.name: agent-bridge
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"
com.docker.network.enable_ipv6: "false"