Skip to content

naorbrig/claude-code-agent-docker

Claude Code Agent Docker

Run autonomous Claude Code agents in Docker with Telegram & Discord

License: MIT Docker Claude Code Telegram Discord PRs Welcome

Zero-touch startup · Persistent state · Multi-agent ready · Fully automated

Quick Start · Configuration · Multi-Agent · Contributing


What is this?

A production-ready Docker setup for running Claude Code agents that communicate through Telegram and Discord. Deploy one agent or a fleet — each with its own identity, channels, and workspace.

The problem: Claude Code is an interactive CLI tool designed for local use. Running it headlessly in a container requires bypassing onboarding wizards, configuring auth tokens, installing channel plugins, and managing state across restarts.

This solution: A single Docker image that handles all of that automatically. Configure via environment variables, deploy with docker compose up -d, and your agent is live on Telegram and Discord.

Features

Feature Description
Zero-touch startup No interactive prompts — onboarding, trust dialogs, and permission screens all pre-configured
Telegram integration Communicate with your agent via Telegram bot (auto-installed plugin)
Discord integration Communicate with your agent via Discord bot (auto-installed plugin)
Persistent state Docker volumes preserve plugins, pairings, sessions, and workspace across restarts
Auto plugin install Telegram and Discord plugins installed automatically on first boot
Multi-agent ready Deploy multiple agents from the same image — just change the identity file
Configurable Agent name, model, resources — all via environment variables
Secure by default Tokens in .env files with 600 permissions, .gitignore for secrets

Architecture

┌─────────────┐         ┌──────────────┐
│  Telegram    │         │   Discord    │
│  Bot API     │         │   Gateway    │
└──────┬──────┘         └──────┬───────┘
       │                       │
       │    ┌──────────────┐   │
       └────┤  MCP Servers ├───┘
            │  (bun)       │
            └──────┬───────┘
                   │
          ┌────────▼────────┐
          │   Claude Code   │
          │   (tmux)        │
          │                 │
          │  ┌───────────┐  │
          │  │ CLAUDE.md  │  │  ← Agent identity
          │  │ (system    │  │
          │  │  prompt)   │  │
          │  └───────────┘  │
          └────────┬────────┘
                   │
     ┌─────────────┼─────────────┐
     │             │             │
┌────▼────┐  ┌────▼────┐  ┌────▼────┐
│ .claude │  │workspace│  │  .env   │
│ volume  │  │ volume  │  │ (host)  │
└─────────┘  └─────────┘  └─────────┘
  plugins      code &       tokens &
  pairings     projects     config
  settings

Quick Start

Prerequisites

1. Clone

git clone https://github.com/naorbrig/claude-code-agent-docker.git
cd claude-code-agent-docker

2. Get a Claude Code OAuth token

On your local machine (requires Claude Code installed):

claude setup-token

Sign in via browser, copy the long-lived token.

3. Configure

cp .env.example .env

Edit .env with your OAuth token and (optionally) bot tokens:

CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-your-token-here
AGENT_NAME=my-agent
AGENT_MODEL=sonnet
TELEGRAM_BOT_TOKEN=123456789:AAH...    # optional
DISCORD_BOT_TOKEN=MTIz...              # optional

4. Customize identity

Edit CLAUDE.md — this is your agent's system prompt. Define its personality, skills, and rules.

5. Deploy

docker compose up -d

6. Pair messaging channels

DM your Telegram or Discord bot. You'll receive a pairing code. Approve it:

# View the agent's screen
docker exec my-agent tmux capture-pane -t my-agent -p

# Approve Telegram pairing
docker exec my-agent tmux send-keys -t my-agent '/telegram:access pair <code>' Enter

# Approve Discord pairing
docker exec my-agent tmux send-keys -t my-agent '/discord:access pair <code>' Enter

Your agent is now live. Send it messages on Telegram or Discord.

Environment Variables

Variable Required Default Description
CLAUDE_CODE_OAUTH_TOKEN Yes OAuth token from claude setup-token
AGENT_NAME No claude Agent display name (used for tmux session, git, and --name)
AGENT_MODEL No sonnet Model: opus, sonnet, or haiku
TELEGRAM_BOT_TOKEN No Telegram bot token from @BotFather
DISCORD_BOT_TOKEN No Discord bot token from Developer Portal
GITHUB_TOKEN No GitHub PAT for git operations inside the container
MEMORY_LIMIT No 8g Container memory limit
CPU_LIMIT No 8 Container CPU limit
MEMORY_RESERVATION No 4g Container memory reservation

Multiple Agents

Deploy a fleet of agents from the same image — each with a different identity and channels.

Option A: Separate directories

agents/
├── alice/
│   ├── .env          # AGENT_NAME=alice, unique tokens
│   └── CLAUDE.md     # Alice's personality
├── bob/
│   ├── .env          # AGENT_NAME=bob, unique tokens
│   └── CLAUDE.md     # Bob's personality
└── shared/
    ├── Dockerfile
    ├── entrypoint.sh
    └── docker-compose.yml

Option B: Single compose file

services:
  alice:
    build: .
    container_name: alice
    init: true
    env_file: agents/alice/.env
    volumes:
      - ./agents/alice/CLAUDE.md:/home/node/CLAUDE.md:ro
      - alice-claude:/home/node/.claude
      - alice-workspace:/home/node/workspace
    restart: unless-stopped

  bob:
    build: .
    container_name: bob
    init: true
    env_file: agents/bob/.env
    volumes:
      - ./agents/bob/CLAUDE.md:/home/node/CLAUDE.md:ro
      - bob-claude:/home/node/.claude
      - bob-workspace:/home/node/workspace
    restart: unless-stopped

volumes:
  alice-claude:
  alice-workspace:
  bob-claude:
  bob-workspace:

Channel Setup

Telegram

  1. Message @BotFather on Telegram → /newbot
  2. Copy the bot token to your .env file
  3. Deploy the container
  4. DM your bot → receive a pairing code → approve it

Discord

  1. Create an application at Discord Developer Portal
  2. Go to Bot tab → copy the token to your .env
  3. Enable Privileged Gateway Intents: Message Content, Server Members, Presence
  4. Invite the bot to your server:
    https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=274877975552&integration_type=0&scope=bot+applications.commands
    

    Tip: Your client ID is the base64-decoded first segment of the bot token.

  5. DM the bot → receive a pairing code → approve it
  6. Add server channels:
    docker exec <container> tmux send-keys -t <agent> '/discord:access group add <channel_id>' Enter

Bot-to-Bot Communication

By default, both plugins ignore messages from other bots. If you're running multiple agents that need to talk to each other, patch the plugin on each container:

Discord

docker exec <container> sed -i \
  's/if (msg.author.bot) return/\/\/ if (msg.author.bot) return/' \
  /home/node/.claude/plugins/marketplaces/claude-plugins-official/external_plugins/discord/server.ts

Telegram

docker exec <container> sed -i \
  's/if (msg.from?.is_bot) return/\/\/ if (msg.from?.is_bot) return/' \
  /home/node/.claude/plugins/marketplaces/claude-plugins-official/external_plugins/telegram/server.ts

Restart the container after patching.

Note: This patch resets on plugin updates — reapply after claude plugin update.

Managing the Agent

# View agent output
docker exec <container> tmux capture-pane -t <agent-name> -p

# Attach to agent session (interactive)
docker exec -it <container> tmux attach -t <agent-name>
# Detach with: Ctrl+B, then D

# Send a Claude Code command
docker exec <container> tmux send-keys -t <agent-name> '/compact' Enter
docker exec <container> tmux send-keys -t <agent-name> '/model opus' Enter

# Restart agent
docker restart <container>

# View container logs
docker logs <container> --tail 30

# Check resource usage
docker stats <container> --no-stream

How It Works

  1. Dockerfile installs Claude Code + Bun on node:22-bookworm, pre-configures ~/.claude.json and settings.local.json to skip all interactive prompts

  2. entrypoint.sh runs on every container start:

    • Patches ~/.claude.json to skip onboarding, trust dialog, and bypass permissions prompt
    • Installs Telegram/Discord plugins if not already present
    • Writes bot tokens from environment variables to plugin .env files (permissions 600)
    • Launches Claude Code inside a tmux session with --channels flags
  3. Docker volumes persist ~/.claude/ (plugins, pairings, settings) and ~/workspace/ (code, projects) across container restarts and rebuilds

Troubleshooting

Problem Solution
"plugin not installed" in Claude Code header Restart the container — plugins install on boot
Bot not responding to DMs Check TELEGRAM_BOT_TOKEN / DISCORD_BOT_TOKEN in .env
Trust dialog appears on restart Run: docker exec <c> python3 -c "..." to patch .claude.json (see entrypoint.sh)
Discord bot offline in member list Enable Privileged Gateway Intents in Discord Developer Portal
Pairing code not appearing Verify the MCP server is running: docker exec <c> ps aux | grep bun
Agent not responding in Discord server Add the channel: /discord:access group add <channel_id>
Bots can't talk to each other Apply the bot-to-bot patch

Requirements

Component Minimum Recommended
Docker 20.10+ 27.0+
Docker Compose 2.0+ 2.29+
RAM 4 GB 8 GB per agent
CPU 2 cores 4+ cores per agent
Disk 5 GB 20 GB per agent
OS Any with Docker Ubuntu 22.04+ / macOS

Security

  • OAuth tokens and bot tokens are stored in .env files (git-ignored) and written to plugin directories with 600 permissions
  • The container runs as the unprivileged node user (UID 1000)
  • --permission-mode bypassPermissions allows the agent to run commands without approval — only use in trusted/sandboxed environments
  • See SECURITY.md for vulnerability reporting

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

License

MIT — use it however you want.


Built for running AI agent teams in production.

Report Bug · Request Feature · Discussions

About

Run autonomous Claude Code agents in Docker with Telegram & Discord — zero-touch startup, persistent state, multi-agent ready

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors