this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Simplify Deployment (#5)

* docs(deploy): simplify deployment without Coolify

Replace Coolify with plain Docker Compose + Caddy + GitHub Actions:
- Debian 13 with Docker installed directly
- Caddy for reverse proxy and auto-SSL
- GitHub Actions for auto-deploy on push to main
- Install mosh, git, and gh CLI for easier server management

Much simpler setup with fewer moving parts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(deploy): add production configs and simplify instructions

- Add docker-compose.prod.yml with Caddy + Netdata
- Add deploy.sh script for auto-deploy
- Add .github/workflows/deploy.yml for CI/CD
- Add Caddyfile.example with basic auth for Netdata
- Update .env.example with NETDATA_CLAIM_TOKEN
- Update .gitignore to exclude Caddyfile (contains secrets)
- Simplify DEPLOY.md to reference existing files
- Remove step numbers from headings
- Use vim instead of nano

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

authored by

Alice
Claude Opus 4.5
and committed by
GitHub
b5256fcc 29e7d75a

+350 -230
+5
.env.example
··· 57 57 # Linux: http://172.17.0.1:3000 (Docker bridge gateway) 58 58 TOOL_WEBHOOK_URL=http://host.docker.internal:3000 59 59 60 + # === Monitoring === 61 + # Optional: Netdata Cloud claim token for remote monitoring/alerts 62 + # Get from: https://app.netdata.cloud 63 + NETDATA_CLAIM_TOKEN= 64 + 60 65 # === Development === 61 66 # Set to 'development' for verbose logging 62 67 NODE_ENV=development
+17
.github/workflows/deploy.yml
··· 1 + name: Deploy 2 + 3 + on: 4 + push: 5 + branches: [main] 6 + 7 + jobs: 8 + deploy: 9 + runs-on: ubuntu-latest 10 + steps: 11 + - name: Deploy via SSH 12 + uses: appleboy/ssh-action@v1 13 + with: 14 + host: ${{ secrets.HOST }} 15 + username: root 16 + key: ${{ secrets.SSH_KEY }} 17 + script: /opt/assistant/deploy.sh
+3
.gitignore
··· 22 22 .env.production.local 23 23 .env.local 24 24 25 + # Caddy config (contains password hash) 26 + Caddyfile 27 + 25 28 # caches 26 29 .eslintcache 27 30 .cache
+17
Caddyfile.example
··· 1 + # Copy to Caddyfile and customize: 2 + # cp Caddyfile.example Caddyfile 3 + # nano Caddyfile 4 + 5 + # Main app - Telegram webhook 6 + assistant.mosphere.at { 7 + reverse_proxy app:3000 8 + } 9 + 10 + # Netdata monitoring - basic auth protected 11 + # Generate password hash: docker run --rm -it caddy caddy hash-password 12 + netdata.assistant.mosphere.at { 13 + basic_auth { 14 + admin $2a$14$REPLACE_WITH_YOUR_HASH 15 + } 16 + reverse_proxy netdata:19999 17 + }
+248 -230
DEPLOY.md
··· 1 - # Deploying to Hetzner CX33 with Coolify 1 + # Deploying to Hetzner VPS 2 2 3 - Complete guide to deploy the ADHD Support Agent on a Hetzner CX33 VPS using Coolify. 3 + Simple deployment using Docker Compose + Caddy + GitHub Actions. 4 4 5 5 ## Prerequisites 6 6 7 7 - Hetzner Cloud account 8 - - Domain name (for HTTPS/webhooks) 9 - - GitHub account (repo must be accessible) 8 + - Domain name (for HTTPS) 9 + - GitHub repo access 10 10 - Telegram bot token (from @BotFather) 11 11 - OpenAI API key (for embeddings) 12 12 13 13 --- 14 14 15 - ## Step 1: Create Hetzner VPS 15 + ## Create Hetzner VPS 16 16 17 17 1. Go to [Hetzner Cloud Console](https://console.hetzner.cloud/) 18 18 2. Create new project or select existing 19 19 3. Click **Add Server** 20 20 4. Configure: 21 - - **Location**: Falkenstein or Nuremberg (Germany) - cheapest 21 + - **Location**: Falkenstein or Nuremberg (cheapest) 22 22 - **Image**: Debian 13 23 - - **Type**: CX33 (4 vCPU, 8GB RAM, 80GB) - €5.49/mo 24 - - **Networking**: Public IPv4 (default) 23 + - **Type**: CX33 (4 vCPU, 8GB RAM) - €5.49/mo 25 24 - **SSH Key**: Add your public key 26 - - **Name**: `assistant` or similar 25 + - **Name**: `assistant` 27 26 5. Click **Create & Buy Now** 28 27 6. Note the IP address 29 28 29 + ### Firewall (Optional) 30 + 31 + In Hetzner Console → **Firewalls** → **Create Firewall**: 32 + - TCP 22 (SSH) 33 + - TCP 80 (HTTP - for Let's Encrypt) 34 + - TCP 443 (HTTPS) 35 + 36 + Apply to your server. 37 + 30 38 --- 31 39 32 - ## Step 2: Point Domain to Server 33 - 34 - Add DNS records for your domain: 40 + ## Point Domain to Server 35 41 42 + Add DNS A record: 36 43 ``` 37 - Type Name Value TTL 38 - A assistant YOUR_SERVER_IP 300 39 - A *.assistant YOUR_SERVER_IP 300 44 + assistant.yourdomain.com → YOUR_SERVER_IP 40 45 ``` 41 46 42 - Example: `assistant.yourdomain.com` → `YOUR_SERVER_IP` 43 - 44 - Wait 5-10 minutes for DNS propagation. 47 + Wait 5-10 minutes for propagation. 45 48 46 49 --- 47 50 48 - ## Step 3: Initial Server Setup 51 + ## Server Setup 49 52 50 - SSH into your server: 51 - 53 + SSH in: 52 54 ```bash 53 55 ssh root@YOUR_SERVER_IP 54 56 ``` 55 57 56 - Run initial setup: 57 - 58 + Update system: 58 59 ```bash 59 - # Update system 60 60 apt update && apt upgrade -y 61 + ``` 61 62 62 - # Set timezone (optional) 63 - timedatectl set-timezone UTC 63 + Install Docker: 64 + ```bash 65 + apt install -y ca-certificates curl 66 + install -m 0755 -d /etc/apt/keyrings 67 + curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc 68 + chmod a+r /etc/apt/keyrings/docker.asc 64 69 65 - # Reboot to apply kernel updates 66 - reboot 70 + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null 71 + 72 + apt update 73 + apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin 67 74 ``` 68 75 69 - ### Firewall (Optional) 76 + Install mosh and git: 77 + ```bash 78 + apt install -y mosh git 79 + ``` 70 80 71 - Use **Hetzner Cloud Firewall** instead of host-based firewalls: 81 + Install GitHub CLI: 82 + ```bash 83 + (type -p wget >/dev/null || (apt update && apt install wget -y)) && mkdir -p -m 755 /etc/apt/keyrings && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg && cat $out | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null && apt update && apt install gh -y 84 + ``` 72 85 73 - 1. In Hetzner Console → **Firewalls** → **Create Firewall** 74 - 2. Add inbound rules: 75 - - TCP 22 (SSH) 76 - - TCP 80 (HTTP - for Let's Encrypt) 77 - - TCP 443 (HTTPS) 78 - - TCP 8000 (Coolify UI - remove after setup) 79 - 3. Apply to your server 86 + Authenticate with GitHub: 87 + ```bash 88 + gh auth login 89 + ``` 80 90 81 - This is cleaner than ufw/iptables, which Docker often bypasses anyway. 91 + Clone the repo: 92 + ```bash 93 + mkdir -p /opt 94 + cd /opt 95 + gh repo clone YOUR_USERNAME/assistant 96 + cd assistant 97 + ``` 82 98 83 99 --- 84 100 85 - ## Step 4: Install Coolify 101 + ## Configure Environment 86 102 87 - SSH back in after reboot: 103 + Copy the example and customize: 104 + ```bash 105 + cp .env.example .env 106 + vim .env 107 + ``` 88 108 109 + Generate random strings for secrets: 89 110 ```bash 90 - ssh root@YOUR_SERVER_IP 111 + openssl rand -hex 32 # For ANTHROPIC_PROXY_SESSION_SECRET 112 + openssl rand -hex 16 # For TELEGRAM_WEBHOOK_SECRET_TOKEN 91 113 ``` 92 114 93 - Install Coolify: 115 + Key values to set: 116 + - `TELEGRAM_BOT_TOKEN` - from @BotFather 117 + - `TELEGRAM_WEBHOOK_URL` - `https://assistant.yourdomain.com/webhook` 118 + - `TELEGRAM_WEBHOOK_SECRET_TOKEN` - generated above 119 + - `ANTHROPIC_PROXY_SESSION_SECRET` - generated above 120 + - `OPENAI_API_KEY` - your OpenAI key 121 + 122 + --- 94 123 124 + ## Configure Caddy 125 + 126 + Copy the example and customize: 95 127 ```bash 96 - curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash 128 + cp Caddyfile.example Caddyfile 129 + vim Caddyfile 97 130 ``` 98 131 99 - This takes 2-5 minutes. When done, you'll see: 100 - 132 + Generate a password hash for Netdata basic auth: 133 + ```bash 134 + docker run --rm -it caddy caddy hash-password 135 + # Enter your password when prompted, copy the hash into Caddyfile 101 136 ``` 102 - Coolify is now running! 103 - Access it at: http://YOUR_IP:8000 104 - ``` 137 + 138 + Replace domains and password hash with your values. 105 139 106 140 --- 107 141 108 - ## Step 5: Configure Coolify 109 - 110 - 1. Open `http://YOUR_SERVER_IP:8000` in your browser 111 - 2. Create admin account (use a strong password) 112 - 3. Complete the setup wizard: 113 - - **Instance Settings**: Set your instance name 114 - - **SSH Key**: Coolify generates one automatically 142 + ## Deploy 115 143 116 - ### Connect GitHub 144 + Start all services (production compose file is included in the repo): 145 + ```bash 146 + docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build 147 + ``` 117 148 118 - 1. Go to **Sources** → **Add New** 119 - 2. Select **GitHub App** (recommended) or **Deploy Key** 120 - 3. Follow the OAuth flow to connect your GitHub account 121 - 4. Grant access to your assistant repository 149 + Check status: 150 + ```bash 151 + docker compose ps 152 + docker compose logs -f app 153 + ``` 122 154 123 155 --- 124 156 125 - ## Step 6: Create the Application Stack 157 + ## Anthropic OAuth 126 158 127 - Your app needs multiple services. In Coolify: 159 + Complete one-time OAuth setup: 128 160 129 - ### 6.1 Create New Project 161 + 1. Open SSH tunnel to access the proxy: 162 + ```bash 163 + # From your local machine 164 + ssh -L 4001:localhost:4001 root@YOUR_SERVER_IP 165 + ``` 130 166 131 - 1. Go to **Projects** → **New Project** 132 - 2. Name: `assistant` 167 + 2. Open http://localhost:4001/auth/device in your browser 133 168 134 - ### 6.2 Add Docker Compose Resource 169 + 3. Complete the OAuth flow 135 170 136 - 1. Inside the project, click **New Resource** 137 - 2. Select **Docker Compose** 138 - 3. Choose **Based on a Git Repository** 139 - 4. Select your repo and branch (`main` or `master`) 140 - 5. Coolify will detect `docker-compose.yml` 171 + 4. Copy the session ID and update `.env`: 172 + ```bash 173 + # On server 174 + nano /opt/assistant/.env 175 + # Set ANTHROPIC_PROXY_SESSION_ID=your_session_id 176 + ``` 141 177 142 - ### 6.3 Configure Environment Variables 143 - 144 - Go to **Environment Variables** and add: 178 + 5. Restart: 179 + ```bash 180 + cd /opt/assistant 181 + docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d 182 + ``` 145 183 146 - ```env 147 - # Required 148 - TELEGRAM_BOT_TOKEN=your_telegram_bot_token 149 - ANTHROPIC_PROXY_SESSION_SECRET=generate_a_32_char_random_string 150 - OPENAI_API_KEY=sk-your-openai-key 151 - TELEGRAM_WEBHOOK_SECRET_TOKEN=generate_another_random_string 152 - 153 - # Set after first OAuth login (Step 8) 154 - ANTHROPIC_PROXY_SESSION_ID=will_set_later 184 + --- 155 185 156 - # Webhook URL (use your domain) 157 - TELEGRAM_WEBHOOK_URL=https://assistant.yourdomain.com/webhook 186 + ## Set Telegram Webhook 158 187 159 - # Tool webhook (internal Docker network) 160 - TOOL_WEBHOOK_URL=http://app:3000 188 + ```bash 189 + curl -X POST "https://api.telegram.org/bot<BOT_TOKEN>/setWebhook" \ 190 + -H "Content-Type: application/json" \ 191 + -d '{ 192 + "url": "https://assistant.yourdomain.com/webhook", 193 + "secret_token": "YOUR_WEBHOOK_SECRET_TOKEN" 194 + }' 161 195 ``` 162 196 163 - Generate random strings: 197 + Verify: 164 198 ```bash 165 - openssl rand -hex 32 # For SESSION_SECRET 166 - openssl rand -hex 16 # For WEBHOOK_SECRET_TOKEN 199 + curl "https://api.telegram.org/bot<BOT_TOKEN>/getWebhookInfo" 167 200 ``` 168 201 169 - ### 6.4 Configure Domains 170 - 171 - 1. Go to the **app** service settings 172 - 2. Under **Domains**, add: `assistant.yourdomain.com` 173 - 3. Enable **HTTPS** (Coolify handles Let's Encrypt automatically) 174 - 4. Set port to `3000` 175 - 176 202 --- 177 203 178 - ## Step 7: Deploy 204 + ## Setup Auto-Deploy 179 205 180 - 1. Click **Deploy** in Coolify 181 - 2. Watch the build logs 182 - 3. First deploy takes 5-10 minutes (building Rust proxy, pulling images) 183 - 4. Subsequent deploys are much faster (cached layers) 206 + ### On Server: Make deploy script executable 184 207 185 - ### Verify Services 208 + The `deploy.sh` script is included in the repo. Just make it executable: 209 + ```bash 210 + chmod +x /opt/assistant/deploy.sh 211 + ``` 186 212 187 - Once deployed, check health: 213 + ### On Server: Add deploy SSH key 188 214 189 215 ```bash 190 - # From your local machine 191 - curl https://assistant.yourdomain.com/health 216 + # Generate deploy key (no passphrase) 217 + ssh-keygen -t ed25519 -f ~/.ssh/deploy_key -N "" 218 + cat ~/.ssh/deploy_key.pub 219 + # Add this to GitHub repo: Settings → Deploy keys (read-only is fine) 192 220 ``` 193 221 194 - Should return: 195 - ```json 196 - {"status":"healthy","services":{"letta":"healthy","anthropic_proxy":"healthy"}} 222 + ```bash 223 + cat ~/.ssh/deploy_key 224 + # Copy the PRIVATE key for GitHub Actions secret 197 225 ``` 198 226 199 - --- 227 + ### On GitHub: Add secrets 200 228 201 - ## Step 8: Anthropic OAuth Setup 229 + Go to repo **Settings → Secrets and variables → Actions**, add: 230 + - `HOST`: Your server IP 231 + - `SSH_KEY`: The private key from above 202 232 203 - The anthropic-proxy needs a one-time OAuth login: 233 + The workflow file (`.github/workflows/deploy.yml`) is already in the repo. 204 234 205 - 1. Open `http://YOUR_SERVER_IP:4001/login` in your browser 206 - 2. Log in with your Anthropic/Claude account 207 - 3. After successful login, you'll see a session ID 208 - 4. Copy the session ID 209 - 5. In Coolify, update the environment variable: 210 - ``` 211 - ANTHROPIC_PROXY_SESSION_ID=your_session_id_here 212 - ``` 213 - 6. Redeploy the stack 235 + Now every push to `main` triggers automatic deployment. 214 236 215 237 --- 216 238 217 - ## Step 9: Set Telegram Webhook 239 + ## Verify 218 240 219 - ```bash 220 - # Set the webhook URL 221 - curl -X POST "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/setWebhook" \ 222 - -H "Content-Type: application/json" \ 223 - -d '{ 224 - "url": "https://assistant.yourdomain.com/webhook", 225 - "secret_token": "YOUR_WEBHOOK_SECRET_TOKEN" 226 - }' 241 + Test the bot: 242 + 1. Open Telegram 243 + 2. Message your bot 244 + 3. Should respond! 227 245 228 - # Verify webhook is set 229 - curl "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getWebhookInfo" 246 + Check health: 247 + ```bash 248 + curl https://assistant.yourdomain.com/health 230 249 ``` 231 250 232 251 --- 233 252 234 - ## Step 10: Test the Bot 253 + ## Monitoring 235 254 236 - 1. Open Telegram 237 - 2. Find your bot (@YourBotName) 238 - 3. Send `/start` or any message 239 - 4. The bot should respond! 255 + Netdata is included for real-time monitoring, exposed via Caddy with basic auth. 240 256 241 - --- 257 + ### Access Netdata 242 258 243 - ## Post-Deployment 259 + Open https://netdata.assistant.yourdomain.com and enter your basic auth credentials. 244 260 245 - ### Secure Coolify UI 261 + ### What you get 246 262 247 - Once everything works, restrict Coolify UI access: 263 + - CPU, RAM, disk, network graphs (1-second resolution) 264 + - Per-container Docker metrics (CPU, memory, I/O) 265 + - ~2 weeks retention by default 248 266 249 - 1. In Hetzner Console → **Firewalls** → Edit your firewall 250 - 2. Remove the TCP 8000 rule 251 - 3. Access Coolify through SSH tunnel instead: 252 - ```bash 253 - ssh -L 8000:localhost:8000 root@YOUR_SERVER_IP 254 - # Then open http://localhost:8000 267 + ### Optional: Netdata Cloud 268 + 269 + For alerts and multi-server dashboards: 270 + 271 + 1. Sign up at https://app.netdata.cloud 272 + 2. Get your claim token 273 + 3. Add to `.env`: 255 274 ``` 275 + NETDATA_CLAIM_TOKEN=your_token 276 + ``` 277 + 4. Restart: `docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d` 256 278 257 - ### Enable Auto-Deploy 279 + --- 258 280 259 - In Coolify, go to your resource and enable **Webhooks**: 260 - - Push to your repo → automatic redeploy 281 + ## Maintenance 261 282 262 - ### Monitor Resources 283 + ### View logs 284 + ```bash 285 + cd /opt/assistant 286 + docker compose logs -f # All services 287 + docker compose logs -f app # Just the bot 288 + docker compose logs -f letta # Just Letta 289 + ``` 263 290 264 - Coolify Dashboard shows: 265 - - CPU/Memory usage per service 266 - - Container logs 267 - - Deployment history 291 + ### Restart services 292 + ```bash 293 + docker compose -f docker-compose.yml -f docker-compose.prod.yml restart 294 + ``` 268 295 269 - ### Backups 296 + ### Manual deploy 297 + ```bash 298 + /opt/assistant/deploy.sh 299 + ``` 270 300 271 - 1. Go to **Servers** → Your server → **Backup** 272 - 2. Configure automatic backups for: 273 - - `letta-data` volume (PostgreSQL) 274 - - `./data` directory (SQLite) 301 + ### Update SSL cert (automatic) 302 + Caddy handles Let's Encrypt automatically. No action needed. 303 + 304 + ### Backup data 305 + ```bash 306 + # SQLite database 307 + cp /opt/assistant/data/assistant.db ~/backup/ 308 + 309 + # Letta PostgreSQL (if needed) 310 + docker compose exec letta pg_dump -U letta letta > ~/backup/letta.sql 311 + ``` 275 312 276 313 --- 277 314 278 315 ## Troubleshooting 279 316 280 - ### Check Logs 281 - 282 - In Coolify UI: Click any service → **Logs** 283 - 284 - Or via SSH: 317 + ### Container won't start 285 318 ```bash 286 - docker logs assistant-app-1 -f 287 - docker logs assistant-letta-1 -f 288 - docker logs assistant-litellm-1 -f 319 + docker compose logs <service> 320 + docker compose ps -a 289 321 ``` 290 322 291 - ### Service Won't Start 292 - 323 + ### SSL not working 293 324 ```bash 294 - # Check all containers 295 - docker ps -a 296 - 297 - # Check specific service logs 298 - docker compose -f /path/to/compose logs letta 325 + docker compose logs caddy 326 + # Ensure ports 80/443 are open in Hetzner firewall 327 + # Ensure DNS is pointing to your server 299 328 ``` 300 329 301 - ### Webhook Not Working 302 - 330 + ### Webhook not receiving 303 331 ```bash 304 - # Test webhook endpoint directly 332 + # Test manually 305 333 curl -X POST https://assistant.yourdomain.com/webhook \ 306 334 -H "Content-Type: application/json" \ 307 335 -H "X-Telegram-Bot-Api-Secret-Token: YOUR_SECRET" \ 308 336 -d '{"update_id": 1}' 309 337 ``` 310 338 311 - ### Out of Memory 312 - 313 - If services are crashing, check memory: 339 + ### Out of memory 314 340 ```bash 315 341 docker stats 316 342 free -h 317 - ``` 318 - 319 - CX33 has 8GB, which should be plenty. If issues persist, check for memory leaks in logs. 320 - 321 - ### Reset Everything 322 - 323 - Nuclear option - start fresh: 324 - ```bash 325 - cd /path/to/coolify/project 326 - docker compose down -v # Warning: deletes volumes! 327 - docker compose up -d 343 + # CX33 has 8GB, should be plenty 328 344 ``` 329 345 330 346 --- 331 347 332 - ## Cost Summary 348 + ## Cost 333 349 334 - | Item | Monthly Cost | 335 - |------|-------------| 350 + | Item | Monthly | 351 + |------|---------| 336 352 | Hetzner CX33 | €5.49 | 337 - | Domain (optional, if new) | ~€1/mo | 338 - | Anthropic API | Usage-based | 339 - | OpenAI API (embeddings) | ~$0.01/mo | 340 - | **Total** | **~€6.50/mo + API usage** | 353 + | Domain | ~€1 | 354 + | APIs | Usage-based | 355 + | **Total** | **~€6.50 + API** | 341 356 342 357 --- 343 358 344 - ## Architecture Overview 359 + ## Architecture 345 360 346 361 ``` 347 362 Internet 348 363 349 364 350 365 ┌─────────────────────────────────────────────────────┐ 351 - │ Hetzner CX33 (Debian 13 + Docker + Coolify) │ 366 + │ Hetzner CX33 (Debian 13 + Docker) │ 352 367 │ │ 353 - │ ┌─────────────┐ ┌─────────────────────────┐ │ 354 - │ │ Caddy/Nginx │◄────►│ app (Bun :3000) │ │ 355 - │ │ (Coolify) │ │ - Telegram webhook │ │ 356 - │ │ :443 HTTPS │ │ - Tool dispatcher │ │ 357 - │ └─────────────┘ └──────────┬──────────────┘ │ 358 - │ │ │ 359 - │ ▼ │ 360 - │ ┌─────────────────────────┐ │ 361 - │ │ letta (:8283) │ │ 362 - │ │ - Agent orchestration │ │ 363 - │ │ - Memory (PostgreSQL) │ │ 364 - │ └──────────┬──────────────┘ │ 365 - │ │ │ 366 - │ ▼ │ 367 - │ ┌─────────────────────────┐ │ 368 - │ │ litellm (:4000) │ │ 369 - │ │ - OpenAI-compatible API │ │ 370 - │ └──────────┬──────────────┘ │ 371 - │ │ │ 372 - │ ▼ │ 373 - │ ┌─────────────┐ ┌─────────────────────────┐ │ 374 - │ │auth-adapter │◄────►│ anthropic-proxy (:4001) │ │ 375 - │ │ (:4002) │ │ - OAuth session mgmt │ │ 376 - │ └─────────────┘ └──────────┬──────────────┘ │ 377 - │ │ │ 378 - └──────────────────────────────────┼──────────────────┘ 379 - 380 - 381 - Anthropic API (Claude) 368 + │ ┌──────────────────────────────────────┐ │ 369 + │ │ Caddy (:80/:443) - auto-SSL │ │ 370 + │ │ ├─► app:3000 (assistant.*) │ │ 371 + │ │ └─► netdata:19999 (netdata.*) │ │ 372 + │ └──────────────────────────────────────┘ │ 373 + │ │ │ 374 + │ ▼ │ 375 + │ ┌──────────────────┐ │ 376 + │ │ app (Bun :3000) │ │ 377 + │ │ Telegram webhook │ │ 378 + │ └────────┬─────────┘ │ 379 + │ │ │ 380 + │ ▼ │ 381 + │ ┌──────────────────┐ ┌───────────────┐ │ 382 + │ │ letta (:8283) │ │ netdata │ │ 383 + │ │ Agent + Memory │ │ monitoring │ │ 384 + │ └────────┬─────────┘ └───────────────┘ │ 385 + │ │ │ 386 + │ ▼ │ 387 + │ ┌──────────────────┐ │ 388 + │ │ litellm (:4000) │ │ 389 + │ └────────┬─────────┘ │ 390 + │ │ │ 391 + │ ▼ │ 392 + │ ┌──────────────────┐ │ 393 + │ │ anthropic-proxy │ │ 394 + │ │ (:4001) OAuth │ │ 395 + │ └────────┬─────────┘ │ 396 + └───────────────────┼─────────────────────────────────┘ 397 + 398 + 399 + Anthropic API 382 400 ```
+7
deploy.sh
··· 1 + #!/bin/bash 2 + set -e 3 + 4 + cd /opt/assistant 5 + git pull origin main 6 + docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build 7 + docker image prune -f
+53
docker-compose.prod.yml
··· 1 + # Production overrides for docker-compose.yml 2 + # Usage: docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build 3 + # 4 + # This config adds Caddy reverse proxy with auto-SSL (Let's Encrypt) 5 + # Note: Internal service ports are still exposed but should be blocked by firewall 6 + # Only ports 80/443 should be open in Hetzner Cloud Firewall 7 + 8 + services: 9 + caddy: 10 + image: caddy:2-alpine 11 + restart: unless-stopped 12 + ports: 13 + - "80:80" 14 + - "443:443" 15 + volumes: 16 + - ./Caddyfile:/etc/caddy/Caddyfile:ro 17 + - caddy_data:/data 18 + - caddy_config:/config 19 + networks: 20 + - assistant-net 21 + depends_on: 22 + - app 23 + 24 + # Netdata: Real-time monitoring 25 + # Access via https://netdata.assistant.mosphere.at (basic auth protected) 26 + netdata: 27 + image: netdata/netdata 28 + restart: unless-stopped 29 + hostname: assistant 30 + cap_add: 31 + - SYS_PTRACE 32 + security_opt: 33 + - apparmor:unconfined 34 + volumes: 35 + - netdata_config:/etc/netdata 36 + - netdata_lib:/var/lib/netdata 37 + - netdata_cache:/var/cache/netdata 38 + - /proc:/host/proc:ro 39 + - /sys:/host/sys:ro 40 + - /etc/os-release:/host/etc/os-release:ro 41 + - /var/run/docker.sock:/var/run/docker.sock:ro 42 + environment: 43 + - NETDATA_CLAIM_TOKEN=${NETDATA_CLAIM_TOKEN:-} 44 + - NETDATA_CLAIM_URL=https://app.netdata.cloud 45 + networks: 46 + - assistant-net 47 + 48 + volumes: 49 + caddy_data: 50 + caddy_config: 51 + netdata_config: 52 + netdata_lib: 53 + netdata_cache: