ci: docker新增npm、pnpm镜像配置项

This commit is contained in:
JXDN
2025-08-22 15:27:49 +08:00
parent f3002717f8
commit 2186649107
5 changed files with 183 additions and 141 deletions
+1
View File
@@ -48,6 +48,7 @@ VITE_APP_WEB_API_PREFIX=/api
VITE_APP_CONSOLE_API_PREFIX=/consoleapi
# Docker
NPM_REGISTRY_URL=https://registry.npmmirror.com
QUICK_START_MODE=false
DOCKER_CONTAINER_SUFFIX=
DOCKER_MEMORY_LIMIT=3072M
+1
View File
@@ -48,6 +48,7 @@ VITE_APP_WEB_API_PREFIX=/api
VITE_APP_CONSOLE_API_PREFIX=/consoleapi
# Docker
NPM_REGISTRY_URL=https://registry.npmmirror.com
QUICK_START_MODE=false
DOCKER_CONTAINER_SUFFIX=
DOCKER_MEMORY_LIMIT=3072M
+3
View File
@@ -27,5 +27,8 @@
},
"[plaintext]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[dockercompose]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
@@ -311,10 +311,26 @@ export class AiChatMessageController extends BaseController {
const exists = await this.AiChatRecordService.findOneById(conversationId);
if (!exists.title) {
const title = await this.aiGenerateTitle(
model,
dto.messages as Array<ChatCompletionMessageParam>,
);
let title: string;
// 检查是否有深度思考内容(从最终响应中检查)
const hasReasoningContent = finalResponse?.choices?.[0]?.message?.reasoning_content;
if (hasReasoningContent) {
// 如果有深度思考内容,说明是支持深度思考的模型,使用用户问题前20字符作为标题
const userMessage = dto.messages.find((msg) => msg.role === "user");
const userContent = userMessage?.content || "";
title =
typeof userContent === "string"
? userContent.slice(0, 20) + (userContent.length > 20 ? "..." : "")
: "新对话";
} else {
// 非深度思考模型,使用AI生成标题
title = await this.aiGenerateTitle(
model,
dto.messages as Array<ChatCompletionMessageParam>,
);
}
await this.AiChatRecordService.updateConversation(conversationId, playground.id, {
title,
@@ -565,6 +581,7 @@ export class AiChatMessageController extends BaseController {
let hasToolCalls = false;
let reasoningContent = ""; // 收集深度思考内容
let reasoningStartTime: number | null = null; // 深度思考开始时间
let reasoningEndTime: number | null = null; // 深度思考结束时间
do {
hasToolCalls = false;
@@ -592,6 +609,8 @@ export class AiChatMessageController extends BaseController {
if (!reasoningStartTime) {
reasoningStartTime = Date.now();
}
// 每次收到 reasoning_content 都更新结束时间
reasoningEndTime = Date.now();
reasoningContent += chunk.choices[0].delta.reasoning_content;
res.write(
`data: ${JSON.stringify({
@@ -800,13 +819,12 @@ export class AiChatMessageController extends BaseController {
// 准备 metadata,包含深度思考数据
const metadata: Record<string, any> = {};
if (reasoningContent && reasoningStartTime) {
const endTime = Date.now();
if (reasoningContent && reasoningStartTime && reasoningEndTime) {
metadata.reasoning = {
content: reasoningContent,
startTime: reasoningStartTime,
endTime: endTime,
duration: endTime - reasoningStartTime,
endTime: reasoningEndTime,
duration: reasoningEndTime - reasoningStartTime,
};
}
@@ -835,10 +853,23 @@ export class AiChatMessageController extends BaseController {
const exists = await this.AiChatRecordService.findOneById(conversationId);
if (!exists.title) {
const title = await this.aiGenerateTitle(
model,
dto.messages as Array<ChatCompletionMessageParam>,
);
let title: string;
// 如果有深度思考内容,说明是支持深度思考的模型,使用用户问题前20字符作为标题
if (reasoningContent) {
const userMessage = dto.messages.find((msg) => msg.role === "user");
const userContent = userMessage?.content || "";
title =
typeof userContent === "string"
? userContent.slice(0, 20) + (userContent.length > 20 ? "..." : "")
: "新对话";
} else {
// 非深度思考模型,使用AI生成标题
title = await this.aiGenerateTitle(
model,
dto.messages as Array<ChatCompletionMessageParam>,
);
}
await this.AiChatRecordService.updateConversation(conversationId, playground.id, {
title,
+135 -129
View File
@@ -1,137 +1,143 @@
# 定义通用资源配置
x-resource-config: &resource-config
deploy:
resources:
limits:
memory: ${DOCKER_MEMORY_LIMIT:-3584M}
cpus: '${DOCKER_CPU_LIMIT:-1.0}'
reservations:
memory: ${DOCKER_MEMORY_RESERVATION:-512M}
deploy:
resources:
limits:
memory: ${DOCKER_MEMORY_LIMIT:-3584M}
cpus: "${DOCKER_CPU_LIMIT:-1.0}"
reservations:
memory: ${DOCKER_MEMORY_RESERVATION:-512M}
services:
# Redis 缓存服务
redis:
image: registry.ap-southeast-1.aliyuncs.com/fastbuildai/redis:8.2.0
container_name: fastbuildai-redis${DOCKER_CONTAINER_SUFFIX:-}
restart: always
environment:
TZ: Asia/Shanghai
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
QUICK_START_MODE: ${QUICK_START_MODE:-false}
ports:
- "${REDIS_EXTERNAL_PORT:-}${REDIS_EXTERNAL_PORT:+:}6379"
volumes:
- ./data/redis:/data
networks:
- fastbuildai-network
<<: *resource-config
healthcheck:
test: ["CMD-SHELL", "redis-cli -a $$REDIS_PASSWORD ping"]
interval: 10s
timeout: 5s
retries: 5
# Redis 缓存服务
redis:
image: registry.ap-southeast-1.aliyuncs.com/fastbuildai/redis:8.2.0
container_name: fastbuildai-redis${DOCKER_CONTAINER_SUFFIX:-}
restart: always
environment:
TZ: Asia/Shanghai
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
QUICK_START_MODE: ${QUICK_START_MODE:-false}
ports:
- "${REDIS_EXTERNAL_PORT:-}${REDIS_EXTERNAL_PORT:+:}6379"
volumes:
- ./data/redis:/data
networks:
- fastbuildai-network
<<: *resource-config
healthcheck:
test: ["CMD-SHELL", "redis-cli -a $$REDIS_PASSWORD ping"]
interval: 10s
timeout: 5s
retries: 5
# PostgreSQL 数据库服务 (with pgvector)
postgres:
image: registry.ap-southeast-1.aliyuncs.com/fastbuildai/postgres:17.6
container_name: fastbuildai-postgres${DOCKER_CONTAINER_SUFFIX:-}
restart: always
environment:
TZ: Asia/Shanghai
POSTGRES_USER: ${DB_USERNAME:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
POSTGRES_DB: ${DB_DATABASE:-fastbuildai}
ports:
- "${POSTGRES_EXTERNAL_PORT:-}${POSTGRES_EXTERNAL_PORT:+:}5432"
volumes:
- ./data/postgres/postgres_data:/var/lib/postgresql/data
networks:
- fastbuildai-network
<<: *resource-config
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
# PostgreSQL 数据库服务 (with pgvector)
postgres:
image: registry.ap-southeast-1.aliyuncs.com/fastbuildai/postgres:17.6
container_name: fastbuildai-postgres${DOCKER_CONTAINER_SUFFIX:-}
restart: always
environment:
TZ: Asia/Shanghai
POSTGRES_USER: ${DB_USERNAME:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
POSTGRES_DB: ${DB_DATABASE:-fastbuildai}
ports:
- "${POSTGRES_EXTERNAL_PORT:-}${POSTGRES_EXTERNAL_PORT:+:}5432"
volumes:
- ./data/postgres/postgres_data:/var/lib/postgresql/data
networks:
- fastbuildai-network
<<: *resource-config
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
# Node.js 开发环境
nodejs:
image: registry.ap-southeast-1.aliyuncs.com/fastbuildai/node:22.18.0
container_name: fastbuildai-nodejs${DOCKER_CONTAINER_SUFFIX:-}
restart: on-failure:3
working_dir: /fastbuildai
volumes:
- ../:/fastbuildai
ports:
- "${SERVER_PORT:-4090}:${SERVER_PORT:-4090}"
environment:
TZ: Asia/Shanghai
SERVER_PORT: ${SERVER_PORT:-4090}
QUICK_START_MODE: ${QUICK_START_MODE:-false}
DB_USERNAME: ${DB_USERNAME:-postgres}
DB_PASSWORD: ${DB_PASSWORD:-postgres}
DB_DATABASE: ${DB_DATABASE:-fastbuildai}
DB_HOST: postgres
DB_PORT: 5432
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
command: |
sh -c '
set -e
echo "🚀 Starting FastbuildAI container..."
if [ -z "$$QUICK_START_MODE" ]; then
QUICK_START_MODE="false"
echo "⚠️ QUICK_START_MODE is empty, setting default value: false"
fi
echo "🔍 Debug: QUICK_START_MODE = [$$QUICK_START_MODE]"
if ! command -v pnpm >/dev/null 2>&1; then
echo "📦 Installing pnpm..."
npm config set registry https://registry.npmmirror.com
npm install -g pnpm
fi
echo "📦 Installing dependencies..."
if [ -d "node_modules" ]; then
echo "📁 node_modules exists, using force install..."
yes | pnpm i
else
echo "📁 node_modules not found, installing..."
pnpm i
fi
if [ ! -f "/fastbuildai/public/index.html" ] || [ "$$QUICK_START_MODE" = "false" ]; then
echo "🌐 Building web application..."
pnpm --filter ./apps/web run generate
fi
if [ ! -d "/fastbuildai/apps/server/dist" ] || [ "$$QUICK_START_MODE" = "false" ]; then
echo "🔧 Building server application..."
pnpm --filter ./apps/server run build
fi
echo "🔍 Debug: QUICK_START_MODE = [$$QUICK_START_MODE]"
echo "🎯 Starting production server..."
exec pnpm --filter ./apps/server run start:prod
'
networks:
- fastbuildai-network
<<: *resource-config
depends_on:
redis:
condition: service_healthy
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "ps aux | grep 'dist/main' | grep -v grep || exit 1"]
interval: 30s
timeout: 10s
retries: 10
start_period: 180s
# Node.js 开发环境
nodejs:
image: registry.ap-southeast-1.aliyuncs.com/fastbuildai/node:22.18.0
container_name: fastbuildai-nodejs${DOCKER_CONTAINER_SUFFIX:-}
restart: on-failure:3
working_dir: /fastbuildai
volumes:
- ../:/fastbuildai
ports:
- "${SERVER_PORT:-4090}:${SERVER_PORT:-4090}"
environment:
TZ: Asia/Shanghai
SERVER_PORT: ${SERVER_PORT:-4090}
QUICK_START_MODE: ${QUICK_START_MODE:-false}
DB_USERNAME: ${DB_USERNAME:-postgres}
DB_PASSWORD: ${DB_PASSWORD:-postgres}
DB_DATABASE: ${DB_DATABASE:-fastbuildai}
DB_HOST: postgres
DB_PORT: 5432
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
command: |
sh -c '
set -e
echo "🚀 Starting FastbuildAI container..."
if [ -z "$$QUICK_START_MODE" ]; then
QUICK_START_MODE="false"
echo "⚠️ QUICK_START_MODE is empty, setting default value: false"
fi
echo "🔍 Debug: QUICK_START_MODE = [$$QUICK_START_MODE]"
if ! command -v pnpm >/dev/null 2>&1; then
echo "📦 Installing pnpm..."
if [ -n "$$NPM_REGISTRY_URL" ]; then
echo "🔧 Using custom registry: $$NPM_REGISTRY_URL"
npm config set registry "$$NPM_REGISTRY_URL"
fi
npm install -g pnpm
if [ -n "$$NPM_REGISTRY_URL" ]; then
pnpm config set registry "$$NPM_REGISTRY_URL"
fi
fi
echo "📦 Installing dependencies..."
if [ -d "node_modules" ]; then
echo "📁 node_modules exists, using force install..."
yes | pnpm i
else
echo "📁 node_modules not found, installing..."
pnpm i
fi
if [ ! -f "/fastbuildai/public/index.html" ] || [ "$$QUICK_START_MODE" = "false" ]; then
echo "🌐 Building web application..."
pnpm --filter ./apps/web run generate
fi
if [ ! -d "/fastbuildai/apps/server/dist" ] || [ "$$QUICK_START_MODE" = "false" ]; then
echo "🔧 Building server application..."
pnpm --filter ./apps/server run build
fi
echo "🔍 Debug: QUICK_START_MODE = [$$QUICK_START_MODE]"
echo "🎯 Starting production server..."
exec pnpm --filter ./apps/server run start:prod
'
networks:
- fastbuildai-network
<<: *resource-config
depends_on:
redis:
condition: service_healthy
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "ps aux | grep 'dist/main' | grep -v grep || exit 1"]
interval: 30s
timeout: 10s
retries: 10
start_period: 180s
networks:
fastbuildai-network:
driver: bridge
fastbuildai-network:
driver: bridge