diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ba8cf31 --- /dev/null +++ b/.env.example @@ -0,0 +1,38 @@ +# Copy to .env for `docker compose up -d --build`. On Coolify, set these as the resource's environment variables. +# Never add ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, CLAUDE_CODE_OAUTH_TOKEN, +# CLAUDE_CODE_USE_BEDROCK or CLAUDE_CODE_USE_VERTEX: the Claude Code provider is subscription-only and refuses to run. + +# Required. Allowed Telegram user ids, comma separated; the first one is the owner (re-login prompts, "Online"). +TELEGRAM_BOT_TOKEN= +TELEGRAM_ALLOWED_USER_IDS= + +# Model every chat uses, log level, container time zone. +TELEGRAM_MODEL=claude-code/claude-opus-5-5 +LOG_LEVEL=Information +TZ=UTC + +# Build: Playwright MCP + Chromium in the image (~+400 MB); Claude Code version (2.1 = newest 2.1.x at build time). +INSTALL_PLAYWRIGHT=true +CLAUDE_CODE_VERSION=2.1 + +# Speech to text for voice notes (empty = off). +OPENAI_API_KEY= +STT_MODEL= + +# Google Calendar (both set = on; each chat connects its own account with /calendar_connect). +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= + +# Default time zone for chats that never ran /timezone (IANA name, e.g. Europe/Berlin; empty = TZ). +DEFAULT_TIMEZONE= + +# Deny-listed variables the agent's processes may see anyway, comma separated (e.g. GH_TOKEN). +PROCESS_ENV_ALLOW= + +# Playwright MCP preset; empty = compose defaults (enabled if built in, headless, chromium, --no-sandbox, playwright-mcp). +# An override of PLAYWRIGHT_EXTRA_ARGS must keep --no-sandbox. +PLAYWRIGHT_ENABLED= +PLAYWRIGHT_HEADLESS= +PLAYWRIGHT_BROWSER= +PLAYWRIGHT_EXTRA_ARGS= +PLAYWRIGHT_COMMAND= diff --git a/.gitignore b/.gitignore index 9308d23..c97b6d3 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ artifacts/ .volcanic/ # Claude Code worktrees and local state .claude/ +# Local compose configuration (secrets) +.env diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c65aa2b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,42 @@ +services: + bot: + build: + context: . + args: + INSTALL_PLAYWRIGHT: ${INSTALL_PLAYWRIGHT:-true} + CLAUDE_CODE_VERSION: ${CLAUDE_CODE_VERSION:-2.1} + restart: unless-stopped + # dotnet does not reap orphans; killed `claude` trees and bash tool children would pile up as zombies. + # docker-init runs as root (the image user), so the agent can't read its /proc/1/environ. + init: true + # Chromium crashes with Docker's 64 MB /dev/shm. + shm_size: 1gb + stop_grace_period: 30s + environment: + - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} + - TELEGRAM_ALLOWED_USER_IDS=${TELEGRAM_ALLOWED_USER_IDS} + - Telegram__Model=${TELEGRAM_MODEL:-claude-code/claude-opus-5-5} + - TZ=${TZ:-UTC} + - Logging__LogLevel__Default=${LOG_LEVEL:-Information} + # Optional features; empty means off / default. + - OPENAI_API_KEY=${OPENAI_API_KEY:-} # speech to text (attachments spec) + - STT_MODEL=${STT_MODEL:-} + - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID:-} # Google Calendar (calendar spec) + - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET:-} + - DEFAULT_TIMEZONE=${DEFAULT_TIMEZONE:-} # chats' default zone (scheduler spec §7); empty → TZ + - PROCESS_ENV_ALLOW=${PROCESS_ENV_ALLOW:-} # deny-listed variables the agent may see, e.g. GH_TOKEN + # Playwright MCP preset (MCP spec). Enabled when the image has it; the preinstalled binary, no npx download. + - PLAYWRIGHT_ENABLED=${PLAYWRIGHT_ENABLED:-${INSTALL_PLAYWRIGHT:-true}} + - PLAYWRIGHT_HEADLESS=${PLAYWRIGHT_HEADLESS:-true} # no display in the container + - PLAYWRIGHT_BROWSER=${PLAYWRIGHT_BROWSER:-} + - PLAYWRIGHT_EXTRA_ARGS=${PLAYWRIGHT_EXTRA_ARGS:---no-sandbox} + - PLAYWRIGHT_COMMAND=${PLAYWRIGHT_COMMAND:-playwright-mcp} + volumes: + - workspaces:/data/workspaces + - agent:/data/agent + - claude:/data/claude + +volumes: + workspaces: + agent: + claude: