Raspberry Pi + Claude Code
A Raspberry Pi as an always-on dev server running Claude Code, reachable from anywhere via Tailscale — and controllable from your phone through a Telegram bot.
Inspired by Elliot Bonneville's bareclaw approach and his phone-to-Mac persistent terminal setup.
Part 1: Raspberry Pi web server with Tailscale
Why a Pi?
- Cheap, silent, low power (~5W) — runs 24/7 without guilt
- Full Linux environment — runs Node, PHP, Python, Docker, anything
- Enough power for serving sites and running Claude Code (Pi 4 with 4GB+ or Pi 5 recommended)
- No cloud bills, no vendor lock-in
Base setup
- Flash Raspberry Pi OS Lite (64-bit) to an SD card with Raspberry Pi Imager
- Enable SSH in the imager settings
- Set hostname, username, password
- Configure Wi-Fi if not using Ethernet
- Boot the Pi, find its IP, and SSH in
ssh user@raspberrypi.local - Update everything
sudo apt update && sudo apt upgrade -y
Install a web server
Nginx is lightweight and works well on the Pi.
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
Site config goes in /etc/nginx/sites-available/. For a simple static site:
server {
listen 80;
server_name mysite.local;
root /var/www/mysite;
index index.html;
}
Symlink to enable:
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
For PHP (e.g. running this wiki or a Kirby site):
sudo apt install php-fpm -y
Then add a location ~ \.php$ block pointing to the PHP-FPM socket.
Install Tailscale
Tailscale creates a private WireGuard mesh network between your devices. No port forwarding, no dynamic DNS, no firewall holes.
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Follow the auth URL to link the Pi to your Tailnet. Once connected, the Pi gets a stable IP (e.g. 100.x.y.z) reachable from any device on the same Tailnet.
Enable Tailscale SSH so you don't need to manage keys separately:
sudo tailscale up --ssh
Now from any device on the Tailnet:
ssh user@raspberry-pi # uses the Tailscale hostname
Tailscale is free for personal use (up to 100 devices). MagicDNS gives your Pi a hostname like
raspberry-pi.tailnet-name.ts.net.
Install Claude Code
# Install Node.js (Claude Code needs Node 18+)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install nodejs -y
# Install Claude Code
npm install -g @anthropic-ai/claude-code
Authenticate with your Anthropic account or Claude Max subscription.
tmux for persistence
SSH sessions die when the connection drops. tmux keeps processes running.
sudo apt install tmux -y
Start a named session:
tmux new -s claude
Detach with Ctrl+b d. Reattach from any SSH session:
tmux attach -t claude
Run Claude Code inside tmux and it survives disconnects, reboots (with a systemd service), and network drops.
Auto-start on boot
Create a systemd service to launch tmux with Claude Code on boot:
sudo tee /etc/systemd/system/claude-tmux.service << 'EOF'
[Unit]
Description=Claude Code in tmux
After=network-online.target
Wants=network-online.target
[Service]
Type=forking
User=pi
ExecStart=/usr/bin/tmux new-session -d -s claude
ExecStop=/usr/bin/tmux kill-session -t claude
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable claude-tmux
Part 2: Telegram bot for phone control
SSH from a phone works but is painful — tiny text, no notifications, connections drop when switching apps. A Telegram bot gives you push notifications, a thumb-friendly keyboard, and persistent message history.
The bareclaw approach
Elliot Bonneville's bareclaw is ~1200 lines of TypeScript that bridges Telegram messages to claude -p. The key insight: instead of building an agent framework, just shell out to the Claude CLI. You get all your MCP servers, CLAUDE.md files, and tool configurations for free.
Architecture:
Phone (Telegram) → Telegram API → bareclaw daemon → claude -p → response → Telegram
- No orchestration layer, no tool registry, no RAG pipeline
- Runs on Claude Max subscription (flat $200/month) instead of per-token API billing
- Claude can read its own source, rewrite adapters, commit, and trigger a restart
Setting up a Telegram bot
- Message @BotFather on Telegram
- Send
/newbot, follow the prompts - Save the bot token (looks like
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)
Option A: bareclaw
Clone and run bareclaw on the Pi:
git clone https://github.com/ebonneville/bareclaw.git
cd bareclaw
npm install
Configure the Telegram bot token and start the daemon inside tmux:
tmux new -s bareclaw
TELEGRAM_BOT_TOKEN=your-token-here node dist/index.js
The daemon runs in tmux — survives SSH disconnects. Tailscale keeps the Pi reachable. Messages from Telegram get routed to claude -p running in the project directory of your choice.
Option B: minimal custom bot
If you want something simpler, a basic Node.js script can bridge Telegram to Claude Code:
import TelegramBot from "node-telegram-bot-api";
import { execSync } from "child_process";
const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, { polling: true });
const ALLOWED_USER_ID = process.env.TELEGRAM_USER_ID;
bot.on("message", async (msg) => {
if (String(msg.from.id) !== ALLOWED_USER_ID) return;
try {
const result = execSync(
`claude -p "${msg.text.replace(/"/g, '\\"')}"`,
{ timeout: 120000, encoding: "utf8", cwd: "/home/pi/projects" }
);
await bot.sendMessage(msg.chat.id, result.slice(0, 4096));
} catch (err) {
await bot.sendMessage(msg.chat.id, `Error: ${err.message.slice(0, 4000)}`);
}
});
npm install node-telegram-bot-api
Always restrict the bot to your own Telegram user ID. Without this check, anyone who discovers the bot can run commands on your Pi.
Option C: OpenClaw
OpenClaw (formerly ClawdBot) is a more full-featured open-source option that supports Telegram, WhatsApp, Discord, and Slack. It runs on a Pi 4+ and uses Docker for sandboxing. Tailscale is recommended for secure remote access.
Workflow
Once running, you can text your Telegram bot from your phone:
- "Check the status of the nginx server"
- "Create a new page in the wiki about Docker"
- "Run the test suite for project X"
- "Show me the last 5 git commits"
- "Fix the CSS bug in the navigation"
Claude Code receives the message, works in the project directory with full access to your tools and CLAUDE.md context, and sends the response back to Telegram.
Security considerations
- Tailscale — devices must be authenticated to your Tailnet. No ports exposed to the public internet.
- Telegram bot — always filter by user ID. Consider adding a passphrase for destructive commands.
- Claude Code — runs with your user's permissions. Be cautious with commands that modify system files or deploy to production.
- SSH — use Tailscale SSH or key-based auth only. Disable password auth in
/etc/ssh/sshd_config.
Further reading
- Claude Code Is All You Need — Elliot Bonneville on bareclaw
- Phone to Mac Persistent Terminal — tmux + Tailscale for phone-to-computer SSH
- Remote AI Coding with Tailscale SSH — Titus Soporan's remote dev setup
- OpenClaw — open-source multi-platform Claude agent
- Tailscale Docs — official setup guides