aitrader/DEPLOY.md

206 lines
6.4 KiB
Markdown
Raw Normal View History

# Deployment auf gemietetem Ubuntu-VPS
End-to-end Anleitung. Annahme: frischer Ubuntu 22.04/24.04 VPS, du hast root via SSH, Domain optional. Trading läuft gegen Kraken **Demo** (kein echtes Geld).
## 0. Was du brauchst
- SSH-Zugriff zum VPS als `root` oder Sudo-User
- Git-Remote (GitHub/GitLab/self-hosted) für lokal↔Server-Sync
- API-Keys: Kraken Demo (https://demo-futures.kraken.com), Gemini, Anthropic, optional CryptoPanic
- Discord-Webhook-URL
- Tailscale-Account (kostenlos, https://tailscale.com)
## 1. Lokales Repo zu Git-Remote pushen
Auf deinem Laptop:
```bash
cd ~/code/aitrader
git init
git add .
git commit -m "initial: aitrader bot + discord notifier"
# auf GitHub: neues *privates* Repo "aitrader" anlegen, dann:
git remote add origin git@github.com:DEIN_USER/aitrader.git
git branch -M main
git push -u origin main
```
> ⚠️ **Repo MUSS privat sein.** `.env` ist via `.gitignore` ausgeschlossen, aber Keys gehören niemals ins Repo.
## 2. VPS vorbereiten
SSH zum VPS und als root:
```bash
# UFW: nur SSH öffentlich
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw enable
ufw status
```
## 3. Tailscale installieren
```bash
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
```
`tailscale up` zeigt einen Login-Link → in Browser öffnen → mit Google/GitHub einloggen → Server taucht in deinem Tailnet auf. Schreib dir den **Tailscale-Hostnamen** auf (z.B. `aitrader-vps`), den nutzt du gleich fürs Dashboard.
```bash
tailscale ip -4 # zeigt 100.x.y.z — die private Tailnet-IP
tailscale status
```
Auch auf **deinem Laptop und Phone** Tailscale installieren und einloggen → alle drei Geräte sind im selben Mesh.
**Test:** Vom Laptop aus `ping aitrader-vps` (Magic-DNS aktiviert in Tailscale-Admin) oder `ping 100.x.y.z`.
## 4. Repo auf den VPS clonen
Als root oder Sudo-User auf dem VPS:
```bash
sudo mkdir -p /opt
cd /opt
sudo git clone https://github.com/DEIN_USER/aitrader.git aitrader
# oder mit SSH-Key:
# sudo git clone git@github.com:DEIN_USER/aitrader.git aitrader
sudo chown -R $USER:$USER /opt/aitrader
cd /opt/aitrader
```
Wenn du **SSH-Keys** für GitHub nutzen willst (für `git pull` ohne Passwort):
```bash
sudo -u aitrader bash -c 'ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519'
sudo cat /home/aitrader/.ssh/id_ed25519.pub
# diesen Pub-Key in GitHub → Settings → Deploy Keys (read-only) fürs Repo eintragen
```
(Der `aitrader`-User wird im nächsten Schritt vom Install-Script erstellt — Reihenfolge: erst install.sh, dann SSH-Key generieren.)
## 5. Install-Script ausführen
```bash
cd /opt/aitrader
sudo bash deploy/install.sh
```
Das macht:
- erstellt System-User `aitrader`
- installiert Python 3.12, uv
- legt venv unter `/opt/aitrader/.venv` an, installiert dependencies
- kopiert systemd-Units nach `/etc/systemd/system/`
## 6. `.env` auf dem Server einrichten
```bash
sudo cp /opt/aitrader/.env.example /opt/aitrader/.env
sudo nano /opt/aitrader/.env
# Trage ein:
# KRAKEN_DEMO_KEY=...
# KRAKEN_DEMO_SECRET=...
# GEMINI_API_KEY=...
# ANTHROPIC_API_KEY=...
# DISCORD_WEBHOOK_URL=...
# CRYPTOPANIC_API_KEY= (optional)
sudo chown aitrader:aitrader /opt/aitrader/.env
sudo chmod 600 /opt/aitrader/.env
```
## 7. Smoke-Tests vor dem Start
```bash
sudo -u aitrader /opt/aitrader/.venv/bin/python /opt/aitrader/scripts/smoke_kraken.py
sudo -u aitrader /opt/aitrader/.venv/bin/python /opt/aitrader/scripts/smoke_ai.py
sudo -u aitrader /opt/aitrader/.venv/bin/python /opt/aitrader/scripts/smoke_discord.py
```
Jeder Test sollte ohne Fehler laufen + der Discord-Webhook sollte 2 Embeds posten.
## 8. Bot + Dashboard als Services starten
```bash
sudo systemctl enable --now aitrader.service
sudo systemctl enable --now aitrader-dashboard.service
sudo systemctl status aitrader aitrader-dashboard
```
Logs live anschauen:
```bash
sudo journalctl -u aitrader -f
sudo journalctl -u aitrader-dashboard -f
```
## 9. Dashboard via Tailscale erreichen
Auf deinem Laptop (Tailscale läuft):
```
http://aitrader-vps:8501
```
oder
```
http://100.x.y.z:8501
```
Port 8501 ist **nicht** öffentlich — UFW blockt ihn, Streamlit lauscht auf `0.0.0.0`, aber der Tailscale-Tunnel ist der einzige Weg rein. Wenn du noch paranoider sein willst, in `aitrader-dashboard.service` `--server.address` auf die Tailscale-IP setzen.
## 10. Updates deployen (Workflow)
Lokal arbeiten, Änderung pushen, Server pullt + restartet:
```bash
# auf dem Laptop
cd ~/code/aitrader
# … Änderungen mit Claude Code …
git add . && git commit -m "fix: foo" && git push
# auf dem VPS
cd /opt/aitrader
sudo -u aitrader git pull
# bei Code-Änderungen reicht restart; bei neuen Dependencies erst:
# sudo -u aitrader /home/aitrader/.local/bin/uv pip install -e .
sudo systemctl restart aitrader aitrader-dashboard
sudo journalctl -u aitrader -f
```
**Tipp:** Falls du häufig deployst, leg dir lokal eine Funktion an:
```bash
# in ~/.bashrc
deploy-aitrader() {
ssh DEIN_VPS 'cd /opt/aitrader && sudo -u aitrader git pull && sudo systemctl restart aitrader aitrader-dashboard && sudo journalctl -u aitrader -n 30'
}
```
## 11. Backup
Die SQLite-DB unter `/opt/aitrader/data/aitrader.db` enthält alle Trades + Decisions. Backup z.B. via cron:
```bash
sudo crontab -e
# Tägliches Backup nach /root/backups
0 3 * * * cp /opt/aitrader/data/aitrader.db /root/backups/aitrader-$(date +\%F).db
```
## Troubleshooting
| Problem | Check |
|---|---|
| `aitrader.service: status=1` | `journalctl -u aitrader -n 100` — meist fehlende ENV-Vars |
| Kraken-Symbol nicht gefunden | Kraken Futures nutzt `PI_XBTUSD`-Symbole. `python -c "import ccxt; x=ccxt.krakenfutures(); x.set_sandbox_mode(True); x.load_markets(); print(list(x.symbols)[:30])"` und `pairs:` in `config.yaml` anpassen |
| Dashboard nicht erreichbar | `sudo ss -tlnp \| grep 8501` (lauscht?), `tailscale ping aitrader-vps` (Mesh ok?) |
| Webhook tot | Discord rate-limit (429)? `journalctl -u aitrader \| grep discord` |
| Bot pausiert | `journalctl \| grep daily_loss_limit_hit` — Risk-Limit greift |
## Sicherheits-Checkliste
- [ ] Repo ist **privat** auf GitHub
- [ ] `.env` hat `chmod 600` und gehört `aitrader:aitrader`
- [ ] UFW: nur Port 22 öffentlich offen
- [ ] Tailscale `up`, Server im Tailnet
- [ ] SSH: Password-Auth aus, nur Key-Auth (`PasswordAuthentication no` in `/etc/ssh/sshd_config`)
- [ ] `exchange.sandbox: true` in `config.yaml`**niemals** versehentlich auf `false`
- [ ] Discord-Webhook regelmäßig rotieren falls geleakt