-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
146 lines (135 loc) · 5.76 KB
/
Copy pathdocker-compose.yml
File metadata and controls
146 lines (135 loc) · 5.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
services:
mysql:
image: mysql:8.0
container_name: aimo-mysql
ports:
# 仅绑定宿主机回环地址,不对局域网/公网暴露;应用容器走内部网络访问
# 本地开发需要从宿主机连接其他工具时仍可用 127.0.0.1:3306
- '127.0.0.1:3306:3306'
volumes:
# MySQL 数据文件映射到外部磁盘
- ./data/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD:-aimo_password}
- MYSQL_DATABASE=${MYSQL_DATABASE:-aimo}
- MYSQL_USER=${MYSQL_USER:-aimo}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-aimo_password}
# 配置 MySQL 字符集
- MYSQL_CHARSET=utf8mb4
- MYSQL_COLLATION=utf8mb4_unicode_ci
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
restart: unless-stopped
healthcheck:
test:
[
'CMD',
'mysqladmin',
'ping',
'-h',
'localhost',
'-u',
'root',
'-p${MYSQL_PASSWORD:-aimo_password}',
]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
app:
# 使用预构建的镜像 (推荐生产环境使用 stable 标签)
image: ghcr.io/ximing/aimo:stable
# 其他可用标签:
# - ghcr.io/ximing/aimo:latest (最新提交,可能不稳定)
# - ghcr.io/ximing/aimo:stable (master 分支稳定版本)
# - ghcr.io/ximing/aimo:v1.0.0 (特定版本)
# 如果需要从源码构建,请注释上面一行,取消下面的注释
# build:
# context: .
# dockerfile: Dockerfile
# image: aimo:latest
container_name: aimo-app
depends_on:
mysql:
condition: service_healthy
ports:
- '3000:3000'
volumes:
# 数据库文件映射到外部磁盘
- ./data/lancedb:/app/lancedb_data
# 附件文件映射到外部磁盘
- ./data/attachments:/app/attachments
environment:
# ===== 基础配置 =====
- NODE_ENV=production
- PORT=3000
# ===== CORS 配置 =====
- CORS_ORIGIN=${CORS_ORIGIN:-http://localhost:3000}
- CORS_CREDENTIALS=${CORS_CREDENTIALS:-true}
# ===== JWT 配置 =====
# 必需:请在 .env 中设置随机密钥(openssl rand -base64 32),生产环境缺失将拒绝启动
- JWT_SECRET=${JWT_SECRET}
# ===== MySQL 数据库配置 =====
- MYSQL_HOST=${MYSQL_HOST:-mysql}
- MYSQL_PORT=${MYSQL_PORT:-3306}
- MYSQL_USER=${MYSQL_USER:-aimo}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-aimo_password}
- MYSQL_DATABASE=${MYSQL_DATABASE:-aimo}
- MYSQL_CONNECTION_LIMIT=${MYSQL_CONNECTION_LIMIT:-10}
# ===== LanceDB 配置 =====
- LANCEDB_STORAGE_TYPE=${LANCEDB_STORAGE_TYPE:-local}
- LANCEDB_PATH=${LANCEDB_PATH:-./lancedb_data}
- LANCEDB_VERSION_RETENTION_DAYS=${LANCEDB_VERSION_RETENTION_DAYS:-7}
# LanceDB S3 配置 (当 LANCEDB_STORAGE_TYPE=s3 时使用)
# - LANCEDB_S3_BUCKET=${LANCEDB_S3_BUCKET}
# - LANCEDB_S3_PREFIX=${LANCEDB_S3_PREFIX:-lancedb}
# - LANCEDB_S3_ENDPOINT=${LANCEDB_S3_ENDPOINT}
# ===== 附件存储配置 =====
- ATTACHMENT_STORAGE_TYPE=${ATTACHMENT_STORAGE_TYPE:-local}
- ATTACHMENT_LOCAL_PATH=${ATTACHMENT_LOCAL_PATH:-./attachments}
- ATTACHMENT_MAX_FILE_SIZE=${ATTACHMENT_MAX_FILE_SIZE:-52428800}
- ATTACHMENT_PRESIGNED_URL_EXPIRY=${ATTACHMENT_PRESIGNED_URL_EXPIRY:-3600}
# 附件允许的 MIME 类型 (逗号分隔)
# - ATTACHMENT_ALLOWED_MIME_TYPES=${ATTACHMENT_ALLOWED_MIME_TYPES}
# 附件 S3 配置 (当 ATTACHMENT_STORAGE_TYPE=s3 时使用)
# - ATTACHMENT_S3_BUCKET=${ATTACHMENT_S3_BUCKET}
# - ATTACHMENT_S3_PREFIX=${ATTACHMENT_S3_PREFIX:-attachments}
# - ATTACHMENT_S3_ENDPOINT=${ATTACHMENT_S3_ENDPOINT}
# - ATTACHMENT_S3_IS_PUBLIC=${ATTACHMENT_S3_IS_PUBLIC:-false}
# - ATTACHMENT_AWS_ACCESS_KEY_ID=${ATTACHMENT_AWS_ACCESS_KEY_ID}
# - ATTACHMENT_AWS_SECRET_ACCESS_KEY=${ATTACHMENT_AWS_SECRET_ACCESS_KEY}
# - ATTACHMENT_AWS_REGION=${ATTACHMENT_AWS_REGION:-us-east-1}
# ===== AWS 全局凭证配置 (所有 S3 服务共用) =====
# - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
# - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
# - AWS_REGION=${AWS_REGION:-us-east-1}
# ===== OpenAI 配置 (文本 Embedding) =====
- OPENAI_API_KEY=${OPENAI_API_KEY}
- OPENAI_MODEL=${OPENAI_MODEL:-text-embedding-3-small}
- OPENAI_BASE_URL=${OPENAI_BASE_URL:-https://api.openai.com/v1}
- OPENAI_EMBEDDING_DIMENSIONS=${OPENAI_EMBEDDING_DIMENSIONS:-1536}
# ===== 多模态 Embedding 配置 (图片/视频) =====
- MULTIMODAL_EMBEDDING_ENABLED=${MULTIMODAL_EMBEDDING_ENABLED:-false}
# - MULTIMODAL_EMBEDDING_MODEL=${MULTIMODAL_EMBEDDING_MODEL:-qwen3-vl-embedding}
# - DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY}
# - DASHSCOPE_BASE_URL=${DASHSCOPE_BASE_URL:-https://dashscope.aliyuncs.com/api/v1}
# - MULTIMODAL_EMBEDDING_DIMENSION=${MULTIMODAL_EMBEDDING_DIMENSION:-1024}
# - MULTIMODAL_EMBEDDING_OUTPUT_TYPE=${MULTIMODAL_EMBEDDING_OUTPUT_TYPE:-dense}
# - MULTIMODAL_EMBEDDING_VIDEO_FPS=${MULTIMODAL_EMBEDDING_VIDEO_FPS:-0.5}
# ===== 定时任务配置 =====
- DB_OPTIMIZATION_CRON=${DB_OPTIMIZATION_CRON:-0 2 * * *}
# ===== 本地化配置 =====
- LOCALE_LANGUAGE=${LOCALE_LANGUAGE:-zh-cn}
- LOCALE_TIMEZONE=${LOCALE_TIMEZONE:-Asia/Shanghai}
restart: unless-stopped
healthcheck:
test:
[
'CMD',
'node',
'-e',
"require('http').get('http://localhost:3000', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s