feat: remove webui
This commit is contained in:
parent
1dee611fb3
commit
e78a302cb9
6 changed files with 9 additions and 112 deletions
|
|
@ -19,12 +19,6 @@
|
|||
# Port 54545 must be reachable from your browser for the OAuth callback.
|
||||
# Run: sbx ports <sandbox-name> --publish 54545:54545/tcp
|
||||
|
||||
# ─── Web interface ────────────────────────────────────────────────────────────
|
||||
|
||||
# Required for ./claude.sh web
|
||||
# WEBUI_USER=claude
|
||||
# WEBUI_PASSWORD=changeme
|
||||
|
||||
# ─── MCP servers (all optional) ───────────────────────────────────────────────
|
||||
|
||||
# GitHub — PAT with repo scope
|
||||
|
|
|
|||
13
CLAUDE.md
13
CLAUDE.md
|
|
@ -8,16 +8,13 @@ This file provides context and guidance for working with this project.
|
|||
|
||||
## Architecture
|
||||
|
||||
Three containers managed by Docker Compose:
|
||||
Two containers managed by Docker Compose:
|
||||
|
||||
- **`claude`** — Claude Code CLI (`node:20-alpine`), runs as the built-in `node` user (UID 1000), isolated to an internal-only Docker network
|
||||
- **`webui`** — Claude Code as a browser terminal via ttyd (`node:20-alpine`), `node` user (UID 1000), same network isolation, basic auth required
|
||||
- **`proxy`** — Squid forward proxy (`alpine:3.21`), `squid` user, bridges the internal network to the internet with an egress allowlist
|
||||
|
||||
Key Docker network property: `claude-internal` has `internal: true`, meaning Docker adds no default gateway. The `claude` and `webui` containers physically cannot reach the internet without going through the `proxy` container.
|
||||
|
||||
The `webui` service reuses `claude/Dockerfile`. Its entrypoint (`claude/webui-entrypoint.sh`) starts `ttyd --credential user:pass claude` instead of `claude` directly.
|
||||
|
||||
Auth supports three modes (checked at startup by `claude.sh`):
|
||||
- `ANTHROPIC_API_KEY` — API key
|
||||
- `CLAUDE_CODE_OAUTH_TOKEN` — 1-year token from `claude setup-token` (headless-friendly)
|
||||
|
|
@ -27,11 +24,10 @@ Auth supports three modes (checked at startup by `claude.sh`):
|
|||
|
||||
```
|
||||
docker-claude/
|
||||
├── claude.sh # Control script: start/stop/run/web/web-stop/update/logs/status/shell
|
||||
├── claude.sh # Control script: start/stop/run/update/logs/status/shell
|
||||
├── docker-compose.yml # Service definitions and network topology
|
||||
├── claude/
|
||||
│ ├── Dockerfile # Claude Code + ttyd (node:20-alpine, UID 1000)
|
||||
│ └── webui-entrypoint.sh # Entrypoint for webui: starts ttyd wrapping claude
|
||||
│ └── Dockerfile # Claude Code (node:20-alpine, UID 1000)
|
||||
├── proxy/
|
||||
│ ├── Dockerfile # Squid proxy sidecar (alpine:3.21, squid user)
|
||||
│ └── squid.conf # Squid ACL config — egress allowlist lives here
|
||||
|
|
@ -45,9 +41,8 @@ docker-claude/
|
|||
|
||||
```bash
|
||||
chmod +x claude.sh build.sh
|
||||
cp .env.example .env # set ANTHROPIC_API_KEY (and WEBUI_PASSWORD for web mode)
|
||||
cp .env.example .env # set ANTHROPIC_API_KEY
|
||||
cd /path/to/project && ./claude.sh start # start proxy + launch Claude (pulls images, mounts CWD)
|
||||
./claude.sh web # start proxy + webui (browser terminal on :7681)
|
||||
./claude.sh update # pull latest images from registry
|
||||
./build.sh # build images locally (development)
|
||||
```
|
||||
|
|
|
|||
26
claude.sh
26
claude.sh
|
|
@ -37,6 +37,7 @@ load_env() {
|
|||
fi
|
||||
}
|
||||
|
||||
# Wrapper so every docker compose call uses the right file and project name.
|
||||
dc() { docker compose -f "$COMPOSE_FILE" -p "$PROJECT" "$@"; }
|
||||
|
||||
# ─── Volume args ──────────────────────────────────────────────────────────────
|
||||
|
|
@ -121,32 +122,12 @@ cmd_shell() {
|
|||
dc run --rm --service-ports --entrypoint /bin/bash "${VOLUME_ARGS[@]}" claude
|
||||
}
|
||||
|
||||
cmd_web() {
|
||||
check_deps; load_env
|
||||
[[ -n "${WEBUI_PASSWORD:-}" ]] \
|
||||
|| { error "WEBUI_PASSWORD is not set. Add it to .env before starting the web interface."; exit 1; }
|
||||
info "Pulling latest images..."
|
||||
dc pull
|
||||
info "Starting proxy and web interface..."
|
||||
dc up -d webui
|
||||
info "Web interface is up → http://0.0.0.0:7681"
|
||||
info "Credentials: ${WEBUI_USER:-claude} / [WEBUI_PASSWORD]"
|
||||
}
|
||||
|
||||
cmd_web_stop() {
|
||||
check_deps
|
||||
info "Stopping web interface..."
|
||||
dc stop webui && dc rm -f webui
|
||||
}
|
||||
|
||||
cmd_help() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [--kube] <command> [args]
|
||||
|
||||
Commands:
|
||||
start [args] Start proxy, launch Claude Code (CLI)
|
||||
web Start proxy + web interface (browser terminal on :7681)
|
||||
web-stop Stop the web interface (keeps proxy running)
|
||||
stop Stop and remove all containers
|
||||
update Pull latest images from the registry
|
||||
logs [svc] Tail logs (default: proxy)
|
||||
|
|
@ -161,13 +142,10 @@ Environment variables (set in .env):
|
|||
ANTHROPIC_API_KEY API key auth
|
||||
CLAUDE_CODE_OAUTH_TOKEN OAuth token auth (from 'claude setup-token')
|
||||
IMAGE_TAG Image tag to use (default: latest)
|
||||
WEBUI_USER Web interface username (default: claude)
|
||||
WEBUI_PASSWORD Required for web mode
|
||||
|
||||
Examples:
|
||||
cd ~/myproject && ./claude.sh start
|
||||
cd ~/myproject && ./claude.sh --kube start
|
||||
./claude.sh web
|
||||
./claude.sh logs proxy
|
||||
./claude.sh shell
|
||||
EOF
|
||||
|
|
@ -184,8 +162,6 @@ done
|
|||
case "${1:-help}" in
|
||||
start|run) shift; cmd_start "$@" ;;
|
||||
stop) cmd_stop ;;
|
||||
web) cmd_web ;;
|
||||
web-stop) cmd_web_stop ;;
|
||||
update) cmd_update ;;
|
||||
logs) shift; cmd_logs "${1:-}" ;;
|
||||
status) cmd_status ;;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ RUN apk add --no-cache \
|
|||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
bash \
|
||||
ttyd
|
||||
bash
|
||||
|
||||
# Install kubectl — architecture-aware, checksum-verified
|
||||
RUN KUBECTL_VERSION=$(curl -fsSL https://dl.k8s.io/release/stable.txt) \
|
||||
|
|
@ -19,9 +18,6 @@ RUN KUBECTL_VERSION=$(curl -fsSL https://dl.k8s.io/release/stable.txt) \
|
|||
&& rm /tmp/kubectl.sha256 \
|
||||
&& chmod +x /usr/local/bin/kubectl
|
||||
|
||||
# Entrypoint used by the webui service (ttyd wrapping claude)
|
||||
COPY --chmod=755 webui-entrypoint.sh /usr/local/bin/webui-entrypoint.sh
|
||||
|
||||
# System-level Claude Code policy — owned by root, not writable by the node user.
|
||||
# Restricts available models; cannot be bypassed via CLI flags or env vars.
|
||||
COPY settings.json /etc/claude-code/managed-settings.json
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Entrypoint for the webui service.
|
||||
# Wraps Claude Code in ttyd (terminal-over-WebSocket) with basic auth.
|
||||
set -euo pipefail
|
||||
|
||||
: "${WEBUI_PASSWORD:?WEBUI_PASSWORD must be set in .env}"
|
||||
WEBUI_USER="${WEBUI_USER:-claude}"
|
||||
WEBUI_PORT="${WEBUI_PORT:-7681}"
|
||||
|
||||
exec ttyd \
|
||||
--port "${WEBUI_PORT}" \
|
||||
--writable \
|
||||
--credential "${WEBUI_USER}:${WEBUI_PASSWORD}" \
|
||||
claude
|
||||
|
|
@ -5,7 +5,7 @@ services:
|
|||
proxy:
|
||||
image: registry.zeidler.dev/docker-public/playground/docker-claude-proxy:${IMAGE_TAG:-latest}
|
||||
networks:
|
||||
- claude-internal # reachable by claude and webui containers
|
||||
- claude-internal # reachable by claude container
|
||||
- proxy-external # has outbound internet access
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
|
|
@ -55,50 +55,6 @@ services:
|
|||
stdin_open: true
|
||||
tty: true
|
||||
|
||||
# ─── Claude Code web interface ─────────────────────────────────────────────
|
||||
# Serves Claude Code as a browser terminal via ttyd (port 7681).
|
||||
# Protected by HTTP basic auth — set WEBUI_USER / WEBUI_PASSWORD in .env.
|
||||
# Network isolation is identical to the CLI container.
|
||||
webui:
|
||||
image: registry.zeidler.dev/docker-public/playground/docker-claude-claude:${IMAGE_TAG:-latest}
|
||||
entrypoint: ["/usr/local/bin/webui-entrypoint.sh"]
|
||||
depends_on:
|
||||
proxy:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- claude-internal # only — no route to the internet
|
||||
environment:
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
|
||||
- CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN:-}
|
||||
- HTTP_PROXY=http://proxy:3128
|
||||
- HTTPS_PROXY=http://proxy:3128
|
||||
- ALL_PROXY=http://proxy:3128
|
||||
- NO_PROXY=localhost,127.0.0.1
|
||||
# MCP server credentials — all optional; servers are skipped if unset
|
||||
- GITHUB_TOKEN=${GITHUB_TOKEN:-}
|
||||
- GITLAB_TOKEN=${GITLAB_TOKEN:-}
|
||||
- GITLAB_URL=${GITLAB_URL:-https://gitlab.com}
|
||||
- ATLASSIAN_SITE_NAME=${ATLASSIAN_SITE_NAME:-}
|
||||
- ATLASSIAN_USER_EMAIL=${ATLASSIAN_USER_EMAIL:-}
|
||||
- ATLASSIAN_API_TOKEN=${ATLASSIAN_API_TOKEN:-}
|
||||
- WEBUI_USER=${WEBUI_USER:-claude}
|
||||
- WEBUI_PASSWORD=${WEBUI_PASSWORD:-}
|
||||
- WEBUI_PORT=7681
|
||||
ports:
|
||||
- "0.0.0.0:7681:7681"
|
||||
# OAuth callback — required for browser-based login (claude login)
|
||||
- "0.0.0.0:54545:54545"
|
||||
volumes:
|
||||
- claude-config:/home/node/.claude
|
||||
- claude-web-workspace:/workspace
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
stdin_open: true
|
||||
tty: true
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
# Internal-only: Docker adds no default gateway → no direct internet route
|
||||
claude-internal:
|
||||
|
|
@ -109,9 +65,3 @@ networks:
|
|||
proxy-external:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
# Persists Claude Code auth credentials (~/.claude/) across container runs.
|
||||
# Shared between the CLI and web interface so login carries over.
|
||||
claude-config:
|
||||
# Persistent workspace for the web interface
|
||||
claude-web-workspace:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue