Docker 部署
本文介绍如何使用 Docker Compose 一键部署 Snail AI 全套服务,包括数据库、向量存储、后端服务和前端 Nginx。
前提条件
| 软件 | 最低版本 | 说明 |
|---|---|---|
| Docker | 20.10+ | 容器运行时 |
| Docker Compose | v2.0+ | 编排工具(推荐使用 docker compose V2 命令) |
资源建议
最低配置:2 核 CPU、4 GB 内存、20 GB 磁盘。推荐配置:4 核 CPU、8 GB 内存、50 GB 磁盘。
快速启动(3 步完成)
bash
# 1. 克隆仓库并进入部署目录
git clone https://gitee.com/aizuda/snail-ai.git
cd snail-ai/deploy/docker
# 2. 修改环境变量(可选,默认值即可体验)
cp .env.example .env
# 按需编辑 .env 文件
# 3. 一键启动所有服务
docker compose up -d启动完成后,访问 http://localhost:9528 即可进入系统。
- 默认用户名:
admin - 默认密码:
admin123
docker-compose.yml 完整示例
以下为使用 MySQL + PgVector 的标准部署配置,你也可以根据实际情况替换为 PostgreSQL、达梦等数据库。
yaml
version: "3.8"
services:
# ============================================================
# 关系型数据库 -- MySQL
# 如需使用 PostgreSQL 或达梦数据库,请参考下方替换说明
# ============================================================
mysql:
image: mysql:8.0
container_name: snail-ai-mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-snailai123}
MYSQL_DATABASE: ${MYSQL_DATABASE:-snail_ai}
MYSQL_CHARACTER_SET_SERVER: utf8mb4
MYSQL_COLLATION_SERVER: utf8mb4_general_ci
ports:
- "${MYSQL_PORT:-3306}:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./init-sql:/docker-entrypoint-initdb.d # 初始化 SQL 脚本
command: >
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--max_connections=500
networks:
- snail-ai-net
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
# ============================================================
# 向量数据库 -- PgVector(基于 PostgreSQL + pgvector 扩展)
# ============================================================
pgvector:
image: pgvector/pgvector:pg16
container_name: snail-ai-pgvector
restart: always
environment:
POSTGRES_USER: ${PGVECTOR_USER:-postgres}
POSTGRES_PASSWORD: ${PGVECTOR_PASSWORD:-snailai123}
POSTGRES_DB: ${PGVECTOR_DB:-snail_ai_vector}
ports:
- "${PGVECTOR_PORT:-5432}:5432"
volumes:
- pgvector_data:/var/lib/postgresql/data
networks:
- snail-ai-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# ============================================================
# Snail AI 后端服务
# ============================================================
snail-ai-server:
image: opensnail/snail-ai-server:latest
container_name: snail-ai-server
restart: always
depends_on:
mysql:
condition: service_healthy
pgvector:
condition: service_healthy
environment:
# ---------- 数据库连接 ----------
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/${MYSQL_DATABASE:-snail_ai}?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: ${MYSQL_ROOT_PASSWORD:-snailai123}
SPRING_DATASOURCE_DRIVER_CLASS_NAME: com.mysql.cj.jdbc.Driver
# ---------- 向量存储 ----------
SPRING_AI_VECTORSTORE_PGVECTOR_ENABLED: "true"
SPRING_DATASOURCE_PGVECTOR_URL: jdbc:postgresql://pgvector:5432/${PGVECTOR_DB:-snail_ai_vector}
SPRING_DATASOURCE_PGVECTOR_USERNAME: ${PGVECTOR_USER:-postgres}
SPRING_DATASOURCE_PGVECTOR_PASSWORD: ${PGVECTOR_PASSWORD:-snailai123}
# ---------- 存储 ----------
SNAIL_AI_STORAGE_TYPE: ${STORAGE_TYPE:-LOCAL}
SNAIL_AI_STORAGE_LOCAL_PATH: /data/storage
# ---------- 加密密钥 ----------
SNAIL_AI_CRYPTO_KEY: ${SNAIL_AI_CRYPTO_KEY:-}
SNAIL_AI_CRYPTO_IV: ${SNAIL_AI_CRYPTO_IV:-}
# ---------- JVM ----------
JAVA_OPTS: >-
-Xms512m -Xmx1g
-XX:+UseG1GC
-Djava.security.egd=file:/dev/./urandom
ports:
- "${SERVER_HTTP_PORT:-8080}:8080"
- "${SERVER_GRPC_PORT:-18888}:18888"
volumes:
- server_storage:/data/storage
- server_logs:/app/logs
networks:
- snail-ai-net
# ============================================================
# 前端 Nginx
# ============================================================
nginx:
image: opensnail/snail-ai-admin:latest
container_name: snail-ai-nginx
restart: always
depends_on:
- snail-ai-server
ports:
- "${NGINX_PORT:-9528}:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- snail-ai-net
# ============================================================
# 持久化卷
# ============================================================
volumes:
mysql_data:
driver: local
pgvector_data:
driver: local
server_storage:
driver: local
server_logs:
driver: local
# ============================================================
# 网络
# ============================================================
networks:
snail-ai-net:
driver: bridgeNginx 配置示例
配套的 nginx.conf 文件:
nginx
server {
listen 80;
server_name _;
# 前端静态资源
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
# 后端 API 代理
location /api/ {
proxy_pass http://snail-ai-server:8080/;
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;
# SSE 流式输出支持
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
chunked_transfer_encoding on;
}
# gRPC 代理(如果需要外部客户端通过 Nginx 连接)
location /grpc {
grpc_pass grpc://snail-ai-server:18888;
}
}环境变量说明
在 .env 文件中可配置以下变量:
| 变量名 | 默认值 | 说明 |
|---|---|---|
MYSQL_ROOT_PASSWORD | snailai123 | MySQL root 密码 |
MYSQL_DATABASE | snail_ai | MySQL 数据库名 |
MYSQL_PORT | 3306 | MySQL 映射端口 |
PGVECTOR_USER | postgres | PgVector 用户名 |
PGVECTOR_PASSWORD | snailai123 | PgVector 密码 |
PGVECTOR_DB | snail_ai_vector | PgVector 数据库名 |
PGVECTOR_PORT | 5432 | PgVector 映射端口 |
SERVER_HTTP_PORT | 8080 | 后端 HTTP 端口 |
SERVER_GRPC_PORT | 18888 | 后端 gRPC 端口 |
NGINX_PORT | 9528 | 前端访问端口 |
STORAGE_TYPE | LOCAL | 文件存储类型(LOCAL / MINIO) |
SNAIL_AI_CRYPTO_KEY | -- | AES 加密密钥(16 位) |
SNAIL_AI_CRYPTO_IV | -- | AES 加密向量(16 位) |
数据库替换方案
使用 PostgreSQL 替代 MySQL
如果你希望关系型数据库和向量存储共用一个 PostgreSQL 实例(推荐),可以将 mysql 和 pgvector 两个服务合并:
yaml
services:
postgres:
image: pgvector/pgvector:pg16
container_name: snail-ai-postgres
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: snailai123
POSTGRES_DB: snail_ai
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- snail-ai-net同时修改后端环境变量:
yaml
snail-ai-server:
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/snail_ai
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: snailai123
SPRING_DATASOURCE_DRIVER_CLASS_NAME: org.postgresql.Driver
SPRING_AI_VECTORSTORE_PGVECTOR_ENABLED: "true"
SPRING_DATASOURCE_PGVECTOR_URL: jdbc:postgresql://postgres:5432/snail_ai
SPRING_DATASOURCE_PGVECTOR_USERNAME: postgres
SPRING_DATASOURCE_PGVECTOR_PASSWORD: snailai123使用达梦数据库(DM)
yaml
services:
dameng:
image: registry.cn-hangzhou.aliyuncs.com/dameng/dm8:latest
container_name: snail-ai-dameng
restart: always
environment:
LD_LIBRARY_PATH: /opt/dmdbms/bin
INSTANCE_NAME: DMSERVER
ports:
- "5236:5236"
volumes:
- dameng_data:/opt/dmdbms/data
networks:
- snail-ai-net后端环境变量调整:
yaml
SPRING_DATASOURCE_URL: jdbc:dm://dameng:5236/snail_ai
SPRING_DATASOURCE_USERNAME: SYSDBA
SPRING_DATASOURCE_PASSWORD: snailai123
SPRING_DATASOURCE_DRIVER_CLASS_NAME: dm.jdbc.driver.DmDriver使用 Milvus 作为向量存储
如需将向量存储替换为 Milvus(适合大规模向量检索场景),添加以下服务:
yaml
services:
etcd:
image: quay.io/coreos/etcd:v3.5.5
container_name: snail-ai-etcd
environment:
ETCD_AUTO_COMPACTION_MODE: revision
ETCD_AUTO_COMPACTION_RETENTION: "1000"
ETCD_QUOTA_BACKEND_BYTES: "4294967296"
command: >
etcd
--advertise-client-urls=http://0.0.0.0:2379
--listen-client-urls=http://0.0.0.0:2379
--data-dir=/etcd
volumes:
- etcd_data:/etcd
networks:
- snail-ai-net
minio-storage:
image: minio/minio:latest
container_name: snail-ai-milvus-minio
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: minio server /data --console-address ":9001"
volumes:
- milvus_minio_data:/data
networks:
- snail-ai-net
milvus:
image: milvusdb/milvus:v2.4-latest
container_name: snail-ai-milvus
depends_on:
- etcd
- minio-storage
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio-storage:9000
ports:
- "19530:19530"
- "9091:9091"
volumes:
- milvus_data:/var/lib/milvus
networks:
- snail-ai-net数据持久化
所有有状态服务均挂载了 Docker Volume,确保数据在容器重启后不会丢失:
| Volume 名称 | 用途 | 默认位置 |
|---|---|---|
mysql_data | MySQL 数据文件 | /var/lib/mysql |
pgvector_data | PgVector 数据文件 | /var/lib/postgresql/data |
server_storage | 上传的文件、文档等 | /data/storage |
server_logs | 后端日志文件 | /app/logs |
自定义挂载路径
如果需要将数据存放到宿主机指定目录,可修改 Volume 配置为 bind mount:
yaml
volumes:
- /data/snail-ai/mysql:/var/lib/mysql
- /data/snail-ai/pgvector:/var/lib/postgresql/data
- /data/snail-ai/storage:/data/storage
- /data/snail-ai/logs:/app/logs常用运维命令
bash
# 查看所有服务状态
docker compose ps
# 查看后端日志
docker compose logs -f snail-ai-server
# 重启单个服务
docker compose restart snail-ai-server
# 停止所有服务
docker compose down
# 停止并删除数据(慎用)
docker compose down -v
# 更新镜像并重启
docker compose pull && docker compose up -d验证部署
启动完成后,依次验证以下内容:
- 检查服务状态:运行
docker compose ps,确认所有容器状态为running (healthy) - 访问前端页面:浏览器打开
http://localhost:9528,应看到登录页面 - 登录系统:使用
admin/admin123登录 - 检查后端健康:访问
http://localhost:8080/actuator/health,应返回{"status":"UP"} - 配置模型:登录后进入「模型管理」,添加至少一个大模型提供商和模型配置
- 创建智能体:进入「智能体管理」,尝试 AI 辅助创建一个智能体并进行对话
常见问题
- 如果容器启动失败,请先查看
docker compose logs排查原因 - MySQL 初始化脚本执行失败时,可能需要清除 volume 重试:
docker compose down -v && docker compose up -d - 如果前端无法连接后端 API,请检查
nginx.conf中的代理地址是否正确 - 更多排查方法参见 故障排除