Kompletna seoba dva ClaudeClaw Telegram bota (Nikita za Juru, Ana za Zlatka Krešića) s glavnog Plesk servera na novu Plesk-less platformu. Plus duplicirani WhatsApp MCP bridge i multi-account Claude Code (3 accounta).
Glavni server server.2klika.eu hosta 19+ vhostova (Plesk panel, Apache/Nginx, PHP-FPM po verziji). Najteži klijent — first5labs ERP — raste, deserves vlastiti server. Jura je kupio drugi Hetzner. Cilj: clean split.
Ova migracija pokriva samo bots: Nikita (Jurin AI asistent), Ana (Zlatko Krešić, Jurina desna ruka), WhatsApp MCP. ERP migracija dolazi posebno (~30 min downtime, kasnu večer).
add-vhost skripte — isti pattern kao Plesk, bez Pleska.add-vhost / remove-vhost / list-vhosts CLI; per-vhost sysuser (vh-<slug>); end-to-end tested 4×./root/.claude/ (skills/agents/plugins/hooks) + /root/.claude-acc2/ (Jurin credentials). 3 account dirs setup.DELETE FROM sessions u oba bot DB-a → iduća poruka kreće fresh. Dokumentirano u memory./root/CLAUDE.md na jura-serveru (591 linija): RULES s glavnog (#-1, #0, #0b), Radionica v4.1 reference, LEGO princip, Expert Validation, multi-account, bot infrastructure. Bez Plesk reference.server.first5labs.eu (static) + HTML report deploy.| Component | Verzija | Source | Purpose |
|---|---|---|---|
| Ubuntu | 24.04.4 LTS | — | Base OS |
| OpenSSH | system | apt | SSH (key-only, port 6222) |
| fail2ban | system | apt | SSH brute-force protection |
| Caddy | 2.11.3 | cloudsmith stable | Web server + auto SSL |
| Docker CE | 29.5.0 | docker.com | Container runtime |
| Docker Compose | v5.1.3 | docker.com | Orchestration |
| Node.js | 22.22.2 | NodeSource | JS runtime (botovi, gws) |
| Python | 3.12.3 | apt | Scripting + MCP servers |
| Go | 1.26.3 | /usr/local/go | WhatsApp bridge (whatsmeow) |
| uv | 0.11.14 | astral.sh | Python tool installer |
| Claude Code | 2.1.143 | rsync from main | AI CLI |
| gws | 0.22.5 | @googleworkspace/cli (npm) | Google services (Drive/Gmail/Calendar) |
| himalaya | 1.2.0 | binary (musl) | IMAP/SMTP (business email) |
| graphify | 0.8.5 | uv tool install graphifyy | Knowledge graph (Radionica integracija) |
| qrencode | system | apt | WhatsApp QR generation |
U /opt/claude-shared/ (640 MB) — read-only za botove:
| Bot | Owner | Telegram | Claude account | RAM | Service |
|---|---|---|---|---|---|
| Nikita | Jura Šandrk (First5Labs CEO) | @jura_nikita_bot | .claude-acc2 (Jurin Max) | 117 MB | nikita.service |
| Ana | Zlatko Krešić (Jurina desna ruka) | @ana_zlatko_bot | .claude-acc2 (shared) | 190 MB | ana.service |
| WhatsApp bridge | Josip (za Janu Flego u first5labs) | — | — | 61 MB | whatsapp-bridge.service :8080 |
ProtectSystem=strict
PrivateTmp=true
NoNewPrivileges=true
RestrictSUIDSGID=true
ReadWritePaths=/opt/<bot> /root/.claude-acc2 /var/log /run
ReadOnlyPaths=/opt/claude-shared
InaccessiblePaths=/home /root/.ssh
# Per-bot environment
Environment=CLAUDE_CONFIG_DIR=/root/.claude-acc2
Environment=GOOGLE_WORKSPACE_CLI_CONFIG_DIR=/opt/<bot>/.config/gws
Environment=GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file
Environment=HIMALAYA_CONFIG=/opt/<bot>/.config/himalaya/config.toml
Environment=SKILLS_DIR=/opt/<bot>/skills
# Resources
MemoryMax=2G MemoryHigh=1.5G TasksMax=300
| File | Frequency | Što radi |
|---|---|---|
/etc/cron.d/nikita-promo-cleanup | every 2h | Gmail promo cleanup (Jurin) |
/etc/cron.d/nikita-update | daily 04:00 | Claude Code SDK auto-update |
/etc/cron.d/ana-update | daily 04:00 | Claude Code SDK auto-update |
/etc/cron.d/whatsapp-bridge-health | every 30 min | Bridge health check (alert via Molly) |
Tri account-direktorija pripremljena na jura-serveru:
| Direktorij | Account | Purpose |
|---|---|---|
/root/.claude | Jurin (info@first5labs.eu) | Default: Josipov interaktivni rad na jura |
/root/.claude-acc2 | Jurin clone (info@first5labs.eu) | Botovi (Nikita+Ana) pišu odavde — hardcoded u systemd |
/root/.claude-acc3 | — (empty) | Rezerva: Josipov osobni Gmail kad rate-limit hit (claude /login) |
Sva tri imaju chmod 700 root:root. .credentials.json 600. .claude-acc2 ima 15 apsolutnih symlinkova na /root/.claude/ (agents, skills, hooks, plugins, commands, rules, docs, etc.) — shared infrastructure.
PATH sustavski dostupan preko /etc/profile.d/local-bin.sh (claude/graphify/uv u /root/.local/bin/).
WhatsApp dozvoljava do 4 linked devices po accountu. Strategija: dupliciraj — glavni bridge ostane aktivan, jura-server postaje drugi linked device. Kad first5labs ERP migrira, glavni gasimo, jura nastavlja.
38598781506:89@s.whatsapp.net — Josipov broj kao 89. linked device. Bridge sync-ao history kontakata + chatova (DevOps Club, CroAI general, Product Club, Slanica, OG 2 zajebancija, …).
/opt/whatsapp-mcp/whatsapp-bridge/whatsapp-bridge (19 MB binary, port 8080)/opt/whatsapp-mcp/whatsapp-mcp-server/ (stdio interface za Claude Code, on-demand pokretanje)/opt/whatsapp-mcp/whitelist.json (samo 21522450243772@lid = Jan Flego) — fail-closedwhatsapp-allowlist {list,add,remove} za upravljanje whitelistom bez restart-a/etc/cron.d/whatsapp-bridge-health svakih 30 min, alert preko Molly Telegram botaGOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file) — isolated od JosipovogBackup: Hetzner Cloud Backup enabled (~€7/mo). Plus per-project daily DB dumps. Migration secrets backup u /root/migration-secrets-2026-05-16/ (chmod 600).
ExecStart=/usr/bin/node --import tsx src/index.ts ne radi s npm install --omit=dev. Treba full npm install (uključuje tsx). Memory action item: premjestiti tsx u dependencies u package.json botova.
pip freeze > requirements.txt na glavnom, scp na novi, regen venv. Memory action: dodati requirements.txt u repo.
/var/www/vhosts i /root/.claude-walle — ne postoje na jura. Trim za jura-server: InaccessiblePaths=/home /root/.ssh (samo realno postojeći).
.claude-acc2/projects/ i sessions/ ne migriraju (ephemeral state). Prva poruka u svakom chatu pada s "No conversation found with session ID". Bot kaže "Session cleared" ali poruku ne odgovara. Fix: sqlite3 /opt/<bot>/data/<bot>.db "DELETE FROM sessions;" PRIJE prvog start na novom serveru. Dokumentirano u memory reference_bot_migration_session_flush.md.
/root/CLAUDE.md (591 linija) koji NASLJEDUJE pravila s glavnog (RULES #-1, #0, #0b, LEGO, Radionica) ali ima vlastiti context (vhost framework, bot infrastructure, multi-account).
| Task | Trajanje | Downtime | Kada |
|---|---|---|---|
| Smoke test — /start oba bota + WhatsApp Jan ping | 5 min | — | Sad (Josip) |
| first5labseu migracija (static Astro site) | ~20 min | 0 | Bilo kada |
| first5labs ERP migracija (CRITICAL) | ~30 min | ~30 min | Subotom ujutro ili kasnu večer |
| DNS TTL 300s na MyDataKnox za first5labs.eu | 5 min | 0 | 24h PRIJE first5labs migracije |
Telegram alerts setup (/root/secrets/telegram-alerts.env) | 5 min | 0 | Asap (za health checks) |
| Disable WhatsApp bridge na glavnom (nakon first5labs migracije) | 1 min | ~10 sec (rare) | Nakon first5labs |
/opt/server-config/ → git remote (off-server backup) | 15 min | 0 | Bilo kada |
# SSH iz glavnog servera
ssh jura-server
# Bot management
systemctl status|restart|stop nikita | ana | whatsapp-bridge
journalctl -u nikita -f
# DB integrity (bilo kada)
sqlite3 /opt/nikita/data/nikita.db "PRAGMA integrity_check;"
# WhatsApp
whatsapp-allowlist list | add <jid> | remove <jid>
# Vhost
add-vhost <domain> static|proxy|docker [opts]
list-vhosts
remove-vhost <slug> [--keep-data]
# Logs
journalctl -u caddy -f
tail -f /var/log/caddy/<slug>.access.log | jq
fail2ban-client status sshd
| Path | Što |
|---|---|
/root/CLAUDE.md | Server-specific Claude rules (591 linija) |
/opt/server-config/ | Vhost framework + monitoring (git, source na glavnom) |
/opt/vhosts/<slug>/ | Per-vhost root (public/, logs/, tmp/, data/) |
/opt/nikita/, /opt/ana/, /opt/whatsapp-mcp/ | Botovi |
/opt/claude-shared/ | Skills/hooks/memory shared (read-only za botove) |
/root/.claude{,-acc2,-acc3}/ | Multi-account Claude Code |
/root/secrets/ | API keys, Telegram tokens (chmod 700) |
/root/migration-secrets-2026-05-16/ | Migration .env backups (chmod 600) |
/etc/caddy/sites.d/ | Per-vhost Caddy blocks (auto-managed) |
/etc/systemd/system/ | nikita.service, ana.service, whatsapp-bridge.service |
/etc/cron.d/ | nikita-promo-cleanup, *-update, whatsapp-bridge-health |
/var/log/caddy/ | Caddy access logs (JSON, rotated) |