From 223aa25af1a98907a912c4958252678fce3944de Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 10 Jan 2026 02:13:42 -0800 Subject: [PATCH] fix(docker): add health check endpoints and fix IPv6 issue - Add /health endpoints to all NestJS services (user, payment, knowledge, conversation, evolution) - Fix nginx healthcheck to use 127.0.0.1 instead of localhost (IPv6 issue) - Add healthcheck configuration to docker-compose for all backend services - Use start_period to allow services time to initialize before health checks Co-Authored-By: Claude Opus 4.5 --- docker-compose.yml | 37 +++++++++++++++++-- .../conversation-service/src/app.module.ts | 4 ++ .../src/health/health.controller.ts | 9 +++++ .../src/health/health.module.ts | 7 ++++ .../evolution-service/src/app.module.ts | 4 ++ .../src/health/health.controller.ts | 9 +++++ .../src/health/health.module.ts | 7 ++++ .../knowledge-service/src/app.module.ts | 4 ++ .../src/health/health.controller.ts | 9 +++++ .../src/health/health.module.ts | 7 ++++ .../payment-service/src/app.module.ts | 4 ++ .../src/health/health.controller.ts | 9 +++++ .../src/health/health.module.ts | 7 ++++ .../services/user-service/src/app.module.ts | 4 ++ .../src/health/health.controller.ts | 9 +++++ .../user-service/src/health/health.module.ts | 7 ++++ 16 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 packages/services/conversation-service/src/health/health.controller.ts create mode 100644 packages/services/conversation-service/src/health/health.module.ts create mode 100644 packages/services/evolution-service/src/health/health.controller.ts create mode 100644 packages/services/evolution-service/src/health/health.module.ts create mode 100644 packages/services/knowledge-service/src/health/health.controller.ts create mode 100644 packages/services/knowledge-service/src/health/health.module.ts create mode 100644 packages/services/payment-service/src/health/health.controller.ts create mode 100644 packages/services/payment-service/src/health/health.module.ts create mode 100644 packages/services/user-service/src/health/health.controller.ts create mode 100644 packages/services/user-service/src/health/health.module.ts diff --git a/docker-compose.yml b/docker-compose.yml index 1073ef7..7b65e76 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -140,6 +140,12 @@ services: JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d} ports: - "3001:3001" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3001/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s networks: - iconsulting-network @@ -172,6 +178,12 @@ services: STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY} ports: - "3002:3002" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3002/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s networks: - iconsulting-network @@ -204,6 +216,12 @@ services: OPENAI_API_KEY: ${OPENAI_API_KEY} ports: - "3003:3003" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3003/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s networks: - iconsulting-network @@ -236,6 +254,12 @@ services: CORS_ORIGINS: https://iconsulting.szaiai.com,http://localhost:5173 ports: - "3004:3004" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3004/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s networks: - iconsulting-network @@ -264,6 +288,12 @@ services: ANTHROPIC_BASE_URL: ${ANTHROPIC_BASE_URL:-https://api.anthropic.com} ports: - "3005:3005" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3005/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s networks: - iconsulting-network @@ -287,10 +317,11 @@ services: - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/ssl:/etc/nginx/ssl:ro healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"] - interval: 10s - timeout: 5s + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1/health"] + interval: 30s + timeout: 10s retries: 3 + start_period: 10s networks: - iconsulting-network diff --git a/packages/services/conversation-service/src/app.module.ts b/packages/services/conversation-service/src/app.module.ts index 817bb11..cf6dc14 100644 --- a/packages/services/conversation-service/src/app.module.ts +++ b/packages/services/conversation-service/src/app.module.ts @@ -3,6 +3,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ConversationModule } from './conversation/conversation.module'; import { ClaudeModule } from './infrastructure/claude/claude.module'; +import { HealthModule } from './health/health.module'; @Module({ imports: [ @@ -29,6 +30,9 @@ import { ClaudeModule } from './infrastructure/claude/claude.module'; }), }), + // Health check (excluded from global prefix) + HealthModule, + // Feature modules ConversationModule, ClaudeModule, diff --git a/packages/services/conversation-service/src/health/health.controller.ts b/packages/services/conversation-service/src/health/health.controller.ts new file mode 100644 index 0000000..540379a --- /dev/null +++ b/packages/services/conversation-service/src/health/health.controller.ts @@ -0,0 +1,9 @@ +import { Controller, Get } from '@nestjs/common'; + +@Controller() +export class HealthController { + @Get('health') + health() { + return { status: 'ok', timestamp: new Date().toISOString() }; + } +} diff --git a/packages/services/conversation-service/src/health/health.module.ts b/packages/services/conversation-service/src/health/health.module.ts new file mode 100644 index 0000000..7476abe --- /dev/null +++ b/packages/services/conversation-service/src/health/health.module.ts @@ -0,0 +1,7 @@ +import { Module } from '@nestjs/common'; +import { HealthController } from './health.controller'; + +@Module({ + controllers: [HealthController], +}) +export class HealthModule {} diff --git a/packages/services/evolution-service/src/app.module.ts b/packages/services/evolution-service/src/app.module.ts index 206e046..0a65bdf 100644 --- a/packages/services/evolution-service/src/app.module.ts +++ b/packages/services/evolution-service/src/app.module.ts @@ -3,6 +3,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { EvolutionModule } from './evolution/evolution.module'; import { AdminModule } from './admin/admin.module'; +import { HealthModule } from './health/health.module'; @Module({ imports: [ @@ -29,6 +30,9 @@ import { AdminModule } from './admin/admin.module'; }), }), + // Health check + HealthModule, + // 功能模块 EvolutionModule, AdminModule, diff --git a/packages/services/evolution-service/src/health/health.controller.ts b/packages/services/evolution-service/src/health/health.controller.ts new file mode 100644 index 0000000..540379a --- /dev/null +++ b/packages/services/evolution-service/src/health/health.controller.ts @@ -0,0 +1,9 @@ +import { Controller, Get } from '@nestjs/common'; + +@Controller() +export class HealthController { + @Get('health') + health() { + return { status: 'ok', timestamp: new Date().toISOString() }; + } +} diff --git a/packages/services/evolution-service/src/health/health.module.ts b/packages/services/evolution-service/src/health/health.module.ts new file mode 100644 index 0000000..7476abe --- /dev/null +++ b/packages/services/evolution-service/src/health/health.module.ts @@ -0,0 +1,7 @@ +import { Module } from '@nestjs/common'; +import { HealthController } from './health.controller'; + +@Module({ + controllers: [HealthController], +}) +export class HealthModule {} diff --git a/packages/services/knowledge-service/src/app.module.ts b/packages/services/knowledge-service/src/app.module.ts index aa482f8..7615236 100644 --- a/packages/services/knowledge-service/src/app.module.ts +++ b/packages/services/knowledge-service/src/app.module.ts @@ -3,6 +3,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { KnowledgeModule } from './knowledge/knowledge.module'; import { MemoryModule } from './memory/memory.module'; +import { HealthModule } from './health/health.module'; @Module({ imports: [ @@ -29,6 +30,9 @@ import { MemoryModule } from './memory/memory.module'; }), }), + // Health check + HealthModule, + // 功能模块 KnowledgeModule, MemoryModule, diff --git a/packages/services/knowledge-service/src/health/health.controller.ts b/packages/services/knowledge-service/src/health/health.controller.ts new file mode 100644 index 0000000..540379a --- /dev/null +++ b/packages/services/knowledge-service/src/health/health.controller.ts @@ -0,0 +1,9 @@ +import { Controller, Get } from '@nestjs/common'; + +@Controller() +export class HealthController { + @Get('health') + health() { + return { status: 'ok', timestamp: new Date().toISOString() }; + } +} diff --git a/packages/services/knowledge-service/src/health/health.module.ts b/packages/services/knowledge-service/src/health/health.module.ts new file mode 100644 index 0000000..7476abe --- /dev/null +++ b/packages/services/knowledge-service/src/health/health.module.ts @@ -0,0 +1,7 @@ +import { Module } from '@nestjs/common'; +import { HealthController } from './health.controller'; + +@Module({ + controllers: [HealthController], +}) +export class HealthModule {} diff --git a/packages/services/payment-service/src/app.module.ts b/packages/services/payment-service/src/app.module.ts index b644865..6204637 100644 --- a/packages/services/payment-service/src/app.module.ts +++ b/packages/services/payment-service/src/app.module.ts @@ -3,6 +3,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { PaymentModule } from './payment/payment.module'; import { OrderModule } from './order/order.module'; +import { HealthModule } from './health/health.module'; @Module({ imports: [ @@ -26,6 +27,9 @@ import { OrderModule } from './order/order.module'; }), }), + // Health check + HealthModule, + OrderModule, PaymentModule, ], diff --git a/packages/services/payment-service/src/health/health.controller.ts b/packages/services/payment-service/src/health/health.controller.ts new file mode 100644 index 0000000..540379a --- /dev/null +++ b/packages/services/payment-service/src/health/health.controller.ts @@ -0,0 +1,9 @@ +import { Controller, Get } from '@nestjs/common'; + +@Controller() +export class HealthController { + @Get('health') + health() { + return { status: 'ok', timestamp: new Date().toISOString() }; + } +} diff --git a/packages/services/payment-service/src/health/health.module.ts b/packages/services/payment-service/src/health/health.module.ts new file mode 100644 index 0000000..7476abe --- /dev/null +++ b/packages/services/payment-service/src/health/health.module.ts @@ -0,0 +1,7 @@ +import { Module } from '@nestjs/common'; +import { HealthController } from './health.controller'; + +@Module({ + controllers: [HealthController], +}) +export class HealthModule {} diff --git a/packages/services/user-service/src/app.module.ts b/packages/services/user-service/src/app.module.ts index 1ceffbd..bf2fdf3 100644 --- a/packages/services/user-service/src/app.module.ts +++ b/packages/services/user-service/src/app.module.ts @@ -4,6 +4,7 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { JwtModule } from '@nestjs/jwt'; import { UserModule } from './user/user.module'; import { AuthModule } from './auth/auth.module'; +import { HealthModule } from './health/health.module'; @Module({ imports: [ @@ -39,6 +40,9 @@ import { AuthModule } from './auth/auth.module'; global: true, }), + // Health check + HealthModule, + UserModule, AuthModule, ], diff --git a/packages/services/user-service/src/health/health.controller.ts b/packages/services/user-service/src/health/health.controller.ts new file mode 100644 index 0000000..540379a --- /dev/null +++ b/packages/services/user-service/src/health/health.controller.ts @@ -0,0 +1,9 @@ +import { Controller, Get } from '@nestjs/common'; + +@Controller() +export class HealthController { + @Get('health') + health() { + return { status: 'ok', timestamp: new Date().toISOString() }; + } +} diff --git a/packages/services/user-service/src/health/health.module.ts b/packages/services/user-service/src/health/health.module.ts new file mode 100644 index 0000000..7476abe --- /dev/null +++ b/packages/services/user-service/src/health/health.module.ts @@ -0,0 +1,7 @@ +import { Module } from '@nestjs/common'; +import { HealthController } from './health.controller'; + +@Module({ + controllers: [HealthController], +}) +export class HealthModule {}