Joshua Adkisson 4a16621255
All checks were successful
Build and Push / build (push) Successful in 15s
Adding a README.md so I can remember what I did with Claude :D
2026-04-02 11:56:17 -05:00

OpenClaw + Claude Max API Proxy

All-in-one Docker container that runs OpenClaw powered by your Claude Max subscription through the wende/claude-max-api-proxy fork. No separate API key costs.

Architecture

Discord / Telegram / WhatsApp
        ↕
OpenClaw Gateway (:18789)
        ↓
claude-max-api-proxy (:3456)
        ↓
Claude Code CLI (OAuth)
        ↓
Anthropic API (via Max subscription)

Prerequisites

  • A server running Docker (tested on Debian Trixie with CasaOS)
  • A Claude Max subscription
  • A Discord bot token (or Telegram/WhatsApp — see OpenClaw docs)
  • Node.js 22+ is handled inside the container — no host dependency

Container Image

The image is built via Gitea Actions and pushed to the Gitea Container Registry:

gitea.pitthappens.dyndns.org/ragincajunbanjo/openclaw-proxy:latest

Deployment

1. Create data directories

sudo mkdir -p /DATA/AppData/openclaw/{claude,config,workspace}
sudo chown -R 1000:1000 /DATA/AppData/openclaw

2. Log into the Gitea container registry

docker login gitea.pitthappens.dyndns.org

Use your Gitea username and a personal access token with package:read scope.

3. Deploy the container

Use Docker Compose or paste into CasaOS Custom Install:

services:
  openclaw:
    image: gitea.pitthappens.dyndns.org/ragincajunbanjo/openclaw-proxy:latest
    container_name: openclaw
    restart: unless-stopped
    ports:
      - "3456:3456"
      - "18789:18789"
      - "18790:18790"
    volumes:
      - /DATA/AppData/openclaw/claude:/home/node/.claude
      - /DATA/AppData/openclaw/config:/home/node/.openclaw
      - /DATA/AppData/openclaw/workspace:/home/node/.openclaw/workspace
    environment:
      - HOME=/home/node
      - TERM=xterm-256color
      - OPENCLAW_GATEWAY_BIND=lan
      - OPENCLAW_GATEWAY_TOKEN=your-secure-token-here
      - OPENAI_API_KEY=not-needed
      - OPENAI_BASE_URL=http://127.0.0.1:3456/v1
      - TZ=America/Chicago
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://127.0.0.1:3456/health"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    init: true

Generate a secure gateway token with:

openssl rand -hex 32

4. Authenticate Claude Code (one-time)

The container will boot-loop until Claude is authenticated. Stop it first, then run auth in a one-off container:

docker stop openclaw

docker run -it --rm \
  -v /DATA/AppData/openclaw/claude:/home/node/.claude \
  gitea.pitthappens.dyndns.org/ragincajunbanjo/openclaw-proxy:latest \
  /usr/local/bin/entrypoint.sh auth

This starts the Claude Code OAuth flow. You'll get a URL to open in your browser — sign in with your Claude Max account. Credentials are saved to the mounted volume and persist across container restarts.

Start the container after auth completes:

docker start openclaw

5. Configure OpenClaw

Edit the config file directly:

cat > /DATA/AppData/openclaw/config/openclaw.json << 'EOF'
{
  "env": {
    "OPENAI_API_KEY": "not-needed"
  },
  "models": {
    "providers": {
      "claude-proxy": {
        "api": "openai-completions",
        "baseUrl": "http://127.0.0.1:3456/v1",
        "apiKey": "not-needed",
        "models": [
          {
            "id": "claude-sonnet-4",
            "name": "Claude Sonnet 4"
          }
        ]
      }
    }
  },
  "agents": {
    "defaults": {
      "workspace": "/home/node/.openclaw/workspace",
      "model": {
        "primary": "claude-proxy/claude-sonnet-4"
      }
    }
  },
  "gateway": {
    "mode": "local",
    "bind": "lan"
  }
}
EOF

To add more models (e.g. Opus), add entries to the models array:

{
  "id": "claude-opus-4",
  "name": "Claude Opus 4"
}

Then set the primary model to claude-proxy/claude-opus-4.

Restart after editing config:

docker restart openclaw

6. Connect Discord

docker exec -it openclaw bash -c \
  "cd /opt/openclaw && node dist/index.js channels add --channel discord --token YOUR_DISCORD_BOT_TOKEN"

Then DM or mention the bot on Discord. It will respond with a pairing code. Approve it:

docker exec openclaw bash -c \
  "cd /opt/openclaw && node dist/index.js pairing approve discord YOUR_CODE"

Send another message — the bot should now respond.

7. Verify everything is working

# Check logs
docker logs -f openclaw

# Test the proxy directly
docker exec openclaw curl -s http://127.0.0.1:3456/health

# Test a completion
docker exec openclaw curl -s http://127.0.0.1:3456/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-4","messages":[{"role":"user","content":"Hello"}]}'

# Check OpenClaw status
docker exec openclaw bash -c "cd /opt/openclaw && node dist/index.js status"

Updating

After a new image is built by CI:

docker pull gitea.pitthappens.dyndns.org/ragincajunbanjo/openclaw-proxy:latest
docker restart openclaw

Or from CasaOS, use the container's rebuild/update button.

Your config, credentials, and workspace are on persistent volumes and survive updates.


CI/CD Pipeline

Gitea Actions

The repo includes a workflow at .gitea/workflows/build-deploy.yml that builds the Docker image and pushes it to the Gitea Container Registry on every push to main.

Required Gitea Setup

  1. Enable packages and actions in Gitea's app.ini:

    [packages]
    ENABLED = true
    
    [actions]
    ENABLED = true
    DEFAULT_ACTIONS_URL = https://github.com
    

    Restart Gitea after editing.

  2. Install and register an Act Runner on the server:

    sudo wget -O /usr/local/bin/act_runner \
      https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64
    sudo chmod +x /usr/local/bin/act_runner
    
    sudo mkdir -p /opt/gitea-runner
    cd /opt/gitea-runner
    
    sudo act_runner register \
      --instance https://gitea.pitthappens.dyndns.org \
      --name local-runner \
      --labels ubuntu-latest:host
    

    Get the registration token from Gitea → Site Administration → Actions → Runners.

  3. Create a systemd service for the runner:

    sudo tee /etc/systemd/system/gitea-runner.service << 'SVCEOF'
    [Unit]
    Description=Gitea Act Runner
    After=docker.service
    Requires=docker.service
    
    [Service]
    Type=simple
    User=root
    WorkingDirectory=/opt/gitea-runner
    ExecStart=/usr/local/bin/act_runner daemon
    Restart=always
    RestartSec=5
    
    [Install]
    WantedBy=multi-user.target
    SVCEOF
    
    sudo systemctl daemon-reload
    sudo systemctl enable --now gitea-runner
    
  4. Add repo secrets (Repo → Settings → Actions → Secrets):

    • REGISTRY_TOKEN — Gitea personal access token with package:write scope
    • DOCKERHUB_USERNAME — Docker Hub username (avoids pull rate limits during builds)
    • DOCKERHUB_TOKEN — Docker Hub access token

Persistent Volumes

Host Path Container Path Purpose
/DATA/AppData/openclaw/claude /home/node/.claude Claude Code OAuth credentials
/DATA/AppData/openclaw/config /home/node/.openclaw OpenClaw settings and memory
/DATA/AppData/openclaw/workspace /home/node/.openclaw/workspace Agent working directory

Troubleshooting

Problem Solution
Container boot-loops with "No Claude credentials" Run the one-off auth container (Step 4)
"Unknown model" on startup Ensure models.providers is defined in openclaw.json with the correct structure (Step 5)
Proxy returns [object Object] You may have the broken original npm package — rebuild with --no-cache
OAuth token expired Re-run the auth step: docker run -it --rm -v /DATA/AppData/openclaw/claude:/home/node/.claude <image> /usr/local/bin/entrypoint.sh auth
Discord bot doesn't respond Check pairing: docker exec openclaw bash -c "cd /opt/openclaw && node dist/index.js pairing list" and approve any pending codes
"Control UI build failed" in logs Cosmetic only — the gateway works fine without it
Docker Hub rate limit during CI build Add DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets to the repo
OpenClaw requires Node >= 22 Make sure the Dockerfile uses node:22-bookworm-slim as the base image
env: node: No such file or directory Background services (LaunchAgent/systemd) don't inherit shell PATH — use full paths to node

Important Notes

  • The claude-max-api-proxy is a community tool, not officially supported by Anthropic or OpenClaw. It wraps the Claude Code CLI to expose an OpenAI-compatible API using your Max subscription's OAuth credentials.
  • The proxy binds to 127.0.0.1:3456 inside the container. Port 3456 is exposed for debugging but the proxy is only used internally by OpenClaw.
  • This setup uses the wende fork which fixes a serialization bug in the original package that caused responses to return [object Object].
Description
No description provided
Readme 34 KiB
Languages
Shell 58%
Dockerfile 42%