Files
claude-api-proxy/src/index.ts
D8D Developer fafef0e034 feat: 实现 Claude API 透传代理服务
实现完整的 Claude API 代理服务,支持:
- 透传 /v1/* 路径到上游 API
- 流式 (SSE) 和非流式响应
- JSONL 格式请求日志
- /health 健康检查端点
- Docker 多阶段构建
- Gitea Actions CI/CD 工作流

安全加固:
- 容器以非 root 用户运行
- 添加 Docker HEALTHCHECK
- 实现优雅关闭处理 (SIGTERM/SIGINT)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-20 06:47:46 +00:00

50 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dotenv/config';
import express from 'express';
import { proxyHandler } from './proxy.js';
import { healthHandler } from './health.js';
const app = express();
const PORT = parseInt(process.env.PORT || '3000', 10);
// 解析 JSON 请求体,设置较大的限制以支持大请求
app.use(express.json({ limit: '50mb' }));
// 健康检查端点
app.get('/health', healthHandler);
// 代理所有 /v1/* 路由
app.all('/v1/*', proxyHandler);
// 启动服务器
const server = app.listen(PORT, () => {
console.log(`Claude API Proxy 服务已启动`);
console.log(`端口: ${PORT}`);
console.log(`上游 API: ${process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com'}`);
console.log(`健康检查: http://localhost:${PORT}/health`);
});
// 优雅关闭处理
let isShuttingDown = false;
function gracefulShutdown(signal: string) {
if (isShuttingDown) return;
isShuttingDown = true;
console.log(`\n收到 ${signal} 信号,开始优雅关闭...`);
// 停止接受新连接
server.close(() => {
console.log('服务器已关闭');
process.exit(0);
});
// 强制退出超时K8S 默认 30 秒宽限期)
setTimeout(() => {
console.log('优雅关闭超时,强制退出');
process.exit(1);
}, 25000);
}
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));