mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-21 21:15:09 +00:00
feat: add Docker support and improve /health endpoint
- Add Dockerfile (node:20-alpine, EXPOSE 3456, ENV for session tokens) - Add docker-compose.yml with restart: unless-stopped - Add .dockerignore - Improve /health: add version, uptime, uptimeHuman, per-pool ready/error status - Listen on 0.0.0.0 for container compatibility - Bump version to 1.4.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
*.md
|
||||||
|
node_modules
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
scripts/
|
||||||
|
start.sh
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY server.mjs ./
|
||||||
|
COPY setup.mjs ./
|
||||||
|
COPY package.json ./
|
||||||
|
|
||||||
|
ENV CLAUDE_SESSION_TOKEN="" \
|
||||||
|
CLAUDE_COOKIES=""
|
||||||
|
|
||||||
|
EXPOSE 3456
|
||||||
|
|
||||||
|
CMD ["node", "server.mjs"]
|
||||||
@@ -28,6 +28,25 @@ The proxy translates OpenAI-compatible `/v1/chat/completions` requests into `cla
|
|||||||
|
|
||||||
## Quick Install
|
## Quick Install
|
||||||
|
|
||||||
|
### Docker (recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git
|
||||||
|
cd openclaw-claude-proxy
|
||||||
|
cp .env.example .env # add your CLAUDE_SESSION_TOKEN / CLAUDE_COOKIES
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Or as a single command if you already have a `.env` ready:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git && cd openclaw-claude-proxy && docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Health check: `curl http://localhost:3456/health`
|
||||||
|
|
||||||
|
### Node.js (local)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone
|
# Clone
|
||||||
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git
|
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
claude-proxy:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "3456:3456"
|
||||||
|
env_file: .env
|
||||||
|
restart: unless-stopped
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "openclaw-claude-proxy",
|
"name": "openclaw-claude-proxy",
|
||||||
"version": "1.3.1",
|
"version": "1.4.0",
|
||||||
"description": "OpenAI-compatible proxy that routes requests through Claude CLI — use your Claude Pro/Max subscription as an OpenClaw model provider",
|
"description": "OpenAI-compatible proxy that routes requests through Claude CLI — use your Claude Pro/Max subscription as an OpenClaw model provider",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
+22
-5
@@ -26,6 +26,9 @@ const TIMEOUT = parseInt(process.env.CLAUDE_TIMEOUT || "300000", 10);
|
|||||||
const POOL_SIZE = parseInt(process.env.CLAUDE_POOL_SIZE || "1", 10);
|
const POOL_SIZE = parseInt(process.env.CLAUDE_POOL_SIZE || "1", 10);
|
||||||
const POOL_MAX_IDLE = parseInt(process.env.CLAUDE_POOL_MAX_IDLE || "60000", 10); // max idle time before recycle
|
const POOL_MAX_IDLE = parseInt(process.env.CLAUDE_POOL_MAX_IDLE || "60000", 10); // max idle time before recycle
|
||||||
|
|
||||||
|
const VERSION = "1.4.0";
|
||||||
|
const START_TIME = Date.now();
|
||||||
|
|
||||||
// Model alias mapping: request model → claude CLI --model arg
|
// Model alias mapping: request model → claude CLI --model arg
|
||||||
const MODEL_MAP = {
|
const MODEL_MAP = {
|
||||||
"claude-opus-4-6": "opus",
|
"claude-opus-4-6": "opus",
|
||||||
@@ -292,13 +295,27 @@ const server = createServer(async (req, res) => {
|
|||||||
return handleChatCompletions(req, res);
|
return handleChatCompletions(req, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET /health — includes pool status
|
// GET /health — includes pool status, version, uptime
|
||||||
if (req.url === "/health") {
|
if (req.url === "/health") {
|
||||||
const poolStatus = {};
|
const poolStatus = {};
|
||||||
for (const [model, arr] of pool) {
|
for (const [model, arr] of pool) {
|
||||||
poolStatus[model] = { total: arr.length, ready: arr.filter(e => e.ready).length };
|
const readyCount = arr.filter(e => e.ready).length;
|
||||||
|
const errorCount = arr.filter(e => !e.ready).length;
|
||||||
|
poolStatus[model] = {
|
||||||
|
total: arr.length,
|
||||||
|
ready: readyCount,
|
||||||
|
error: errorCount,
|
||||||
|
status: readyCount > 0 ? "ready" : "error",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return jsonResponse(res, 200, { status: "ok", pool: poolStatus });
|
const uptimeMs = Date.now() - START_TIME;
|
||||||
|
return jsonResponse(res, 200, {
|
||||||
|
status: "ok",
|
||||||
|
version: VERSION,
|
||||||
|
uptime: uptimeMs,
|
||||||
|
uptimeHuman: `${Math.floor(uptimeMs / 3600000)}h ${Math.floor((uptimeMs % 3600000) / 60000)}m ${Math.floor((uptimeMs % 60000) / 1000)}s`,
|
||||||
|
pool: poolStatus,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Catch-all: try to handle any POST with messages
|
// Catch-all: try to handle any POST with messages
|
||||||
@@ -312,8 +329,8 @@ const server = createServer(async (req, res) => {
|
|||||||
// ── Start ──────────────────────────────────────────────────────────────
|
// ── Start ──────────────────────────────────────────────────────────────
|
||||||
initPool();
|
initPool();
|
||||||
|
|
||||||
server.listen(PORT, "127.0.0.1", () => {
|
server.listen(PORT, "0.0.0.0", () => {
|
||||||
console.log(`openclaw-claude-proxy v1.3.1 listening on http://127.0.0.1:${PORT}`);
|
console.log(`openclaw-claude-proxy v${VERSION} listening on http://0.0.0.0:${PORT}`);
|
||||||
console.log(`Models: ${MODELS.map((m) => m.id).join(", ")}`);
|
console.log(`Models: ${MODELS.map((m) => m.id).join(", ")}`);
|
||||||
console.log(`Claude binary: ${CLAUDE}`);
|
console.log(`Claude binary: ${CLAUDE}`);
|
||||||
console.log(`Timeout: ${TIMEOUT}ms`);
|
console.log(`Timeout: ${TIMEOUT}ms`);
|
||||||
|
|||||||
Reference in New Issue
Block a user