514 lines
14 KiB
Markdown
514 lines
14 KiB
Markdown
---
|
|
title: "DAEMON Backend — Plan d'installation VPS complet"
|
|
type: project
|
|
created: 2026-04-16
|
|
updated: 2026-04-16
|
|
owner: jerem
|
|
agent: DAEMON
|
|
status: active
|
|
priority: p0
|
|
tags:
|
|
- projet/daemon
|
|
- infra
|
|
- vps
|
|
related:
|
|
- "[[_adn/routing-llm]]"
|
|
- "[[_adn/soul]]"
|
|
---
|
|
|
|
# DAEMON Backend — Plan d'installation VPS
|
|
|
|
> Objectif : monter DAEMON sur un VPS dédié Hostinger pour qu'il tourne 24/7. Vault synchro, agents autonomes, accès sécurisé.
|
|
|
|
---
|
|
|
|
## Infos serveur
|
|
|
|
| Élément | Valeur |
|
|
|---|---|
|
|
| **Hébergeur** | Hostinger — VPS dédié |
|
|
| **OS** | Ubuntu 22.04 LTS |
|
|
| **IP** | `76.13.42.203` |
|
|
| **SSH** | Port 22 → sera changé en 2222 |
|
|
| **Domaine** | `jeremunlimited.com` (DNS géré sur OVH) |
|
|
| **Sous-domaine** | `deamon.jeremunlimited.com` → `76.13.42.203` ✅ |
|
|
| **Clé SSH Mac** | `~/.ssh/id_ed25519.pub` (ed25519, jerem@daemon) |
|
|
|
|
---
|
|
|
|
## Prérequis
|
|
|
|
- [x] Commander le VPS dédié Hostinger
|
|
- [x] Générer clé SSH ed25519 sur Mac
|
|
- [x] Créer un compte Doppler (doppler.com)
|
|
- [x] Installer le plugin Git dans Obsidian
|
|
- [x] Ajouter un DNS A record sur OVH : `deamon.jeremunlimited.com` → `76.13.42.203`
|
|
- [ ] Décider : déplacer le vault hors d'iCloud vers `~/Documents/DAEMON` (recommandé quand Git sync actif)
|
|
|
|
---
|
|
|
|
## Phase 1 — Sécurisation serveur
|
|
|
|
```bash
|
|
# 1.1 — Connexion root initiale
|
|
ssh root@76.13.42.203
|
|
|
|
# 1.2 — Mise à jour système
|
|
apt update && apt upgrade -y
|
|
|
|
# 1.3 — Créer utilisateur non-root
|
|
adduser daemon
|
|
usermod -aG sudo daemon
|
|
|
|
# 1.4 — Copier la clé SSH pour le nouvel utilisateur
|
|
mkdir -p /home/daemon/.ssh
|
|
cp ~/.ssh/authorized_keys /home/daemon/.ssh/authorized_keys
|
|
chown -R daemon:daemon /home/daemon/.ssh
|
|
chmod 700 /home/daemon/.ssh && chmod 600 /home/daemon/.ssh/authorized_keys
|
|
|
|
# 1.5 — Durcir SSH (port custom + pas de root + pas de password)
|
|
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
|
|
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
|
|
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
|
|
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
|
|
sed -i 's/#Port 22/Port 2222/' /etc/ssh/sshd_config
|
|
sed -i 's/^Port 22$/Port 2222/' /etc/ssh/sshd_config
|
|
systemctl restart sshd
|
|
|
|
# 1.6 — Firewall UFW
|
|
ufw default deny incoming
|
|
ufw default allow outgoing
|
|
ufw allow 2222/tcp comment 'SSH custom'
|
|
ufw allow 80/tcp comment 'HTTP'
|
|
ufw allow 443/tcp comment 'HTTPS'
|
|
ufw allow 51820/udp comment 'WireGuard VPN'
|
|
ufw --force enable
|
|
|
|
# 1.7 — fail2ban (anti-bruteforce)
|
|
apt install -y fail2ban
|
|
systemctl enable fail2ban && systemctl start fail2ban
|
|
|
|
# 1.8 — Mises à jour auto sécurité
|
|
apt install -y unattended-upgrades
|
|
dpkg-reconfigure -plow unattended-upgrades
|
|
```
|
|
|
|
**Vérification** : `ssh daemon@76.13.42.203 -p 2222` depuis le Mac.
|
|
|
|
---
|
|
|
|
## Phase 2 — Docker
|
|
|
|
```bash
|
|
# 2.1 — Installer Docker (officiel, pas celui de Hostinger)
|
|
curl -fsSL https://get.docker.com | sh
|
|
sudo usermod -aG docker daemon
|
|
|
|
# 2.2 — Se reconnecter pour activer le groupe docker
|
|
exit
|
|
# ssh daemon@76.13.42.203 -p 2222
|
|
|
|
# 2.3 — Vérifier
|
|
docker --version
|
|
docker compose version
|
|
|
|
# 2.4 — Empêcher Docker de bypass le firewall
|
|
sudo tee /etc/docker/daemon.json << 'EOF'
|
|
{
|
|
"iptables": false
|
|
}
|
|
EOF
|
|
sudo systemctl restart docker
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 3 — Gitea (Git privé)
|
|
|
|
```bash
|
|
# 3.1 — Créer la structure
|
|
mkdir -p ~/daemon-infra/{gitea,nginx,openclaw,scripts}
|
|
cd ~/daemon-infra
|
|
|
|
# 3.2 — Docker Compose : Gitea + PostgreSQL
|
|
cat > docker-compose.yml << 'EOF'
|
|
version: "3.9"
|
|
services:
|
|
gitea:
|
|
image: gitea/gitea:1.22
|
|
container_name: gitea
|
|
environment:
|
|
- USER_UID=1000
|
|
- USER_GID=1000
|
|
- GITEA__database__DB_TYPE=postgres
|
|
- GITEA__database__HOST=db:5432
|
|
- GITEA__database__NAME=gitea
|
|
- GITEA__database__USER=gitea
|
|
- GITEA__database__PASSWD=${GITEA_DB_PASS}
|
|
- GITEA__server__ROOT_URL=${GITEA_URL}
|
|
- GITEA__server__SSH_PORT=222
|
|
volumes:
|
|
- ./gitea/data:/data
|
|
ports:
|
|
- "127.0.0.1:3000:3000"
|
|
- "222:22"
|
|
depends_on:
|
|
- db
|
|
restart: always
|
|
db:
|
|
image: postgres:16-alpine
|
|
container_name: gitea-db
|
|
environment:
|
|
- POSTGRES_USER=gitea
|
|
- POSTGRES_PASSWORD=${GITEA_DB_PASS}
|
|
- POSTGRES_DB=gitea
|
|
volumes:
|
|
- ./gitea/postgres:/var/lib/postgresql/data
|
|
restart: always
|
|
EOF
|
|
|
|
# 3.3 — Générer mot de passe DB + .env
|
|
GITEA_DB_PASS=$(openssl rand -base64 24)
|
|
echo "GITEA_DB_PASS=$GITEA_DB_PASS" > .env
|
|
echo "GITEA_URL=http://76.13.42.203:3000/" >> .env
|
|
# Note : GITEA_URL sera changé quand on aura le domaine + HTTPS
|
|
|
|
# 3.4 — Lancer
|
|
docker compose up -d
|
|
|
|
# 3.5 — Vérifier
|
|
docker ps
|
|
curl http://127.0.0.1:3000
|
|
```
|
|
|
|
**Post-install** : aller sur `http://76.13.42.203:3000` pour finaliser le setup Gitea (créer admin, premier repo `daemon-vault`).
|
|
|
|
---
|
|
|
|
## Phase 4 — Coolify (reverse proxy + HTTPS + gestion containers)
|
|
|
|
> Coolify remplace Nginx + certbot. Il gère le reverse proxy (Traefik intégré), les certificats HTTPS automatiques (Let's Encrypt), et offre une interface web pour gérer tous les services.
|
|
|
|
```bash
|
|
# 4.1 — Installer Coolify (script officiel)
|
|
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
|
|
|
# Coolify sera accessible sur http://76.13.42.203:8000
|
|
# Après config VPN → accessible uniquement via http://10.0.0.1:8000
|
|
|
|
# 4.2 — Post-install (dans le navigateur)
|
|
# - Créer le compte admin
|
|
# - Ajouter le serveur local
|
|
# - Configurer le domaine deamon.jeremunlimited.com
|
|
# - Activer HTTPS automatique (Let's Encrypt intégré)
|
|
# - Déployer Gitea, n8n, Uptime Kuma via l'interface Coolify
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 5 — WireGuard VPN (gratuit, open source)
|
|
|
|
```bash
|
|
# 5.1 — Installer WireGuard sur le VPS
|
|
sudo apt install -y wireguard
|
|
|
|
# 5.2 — Générer les clés serveur
|
|
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
|
|
sudo chmod 600 /etc/wireguard/server_private.key
|
|
|
|
# 5.3 — Config serveur
|
|
SERVER_PRIVKEY=$(sudo cat /etc/wireguard/server_private.key)
|
|
sudo tee /etc/wireguard/wg0.conf << EOF
|
|
[Interface]
|
|
PrivateKey = $SERVER_PRIVKEY
|
|
Address = 10.0.0.1/24
|
|
ListenPort = 51820
|
|
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
|
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
|
|
|
[Peer]
|
|
# Mac de Jerem
|
|
PublicKey = <MAC_PUBLIC_KEY>
|
|
AllowedIPs = 10.0.0.2/32
|
|
EOF
|
|
|
|
# 5.4 — Activer
|
|
sudo systemctl enable wg-quick@wg0
|
|
sudo systemctl start wg-quick@wg0
|
|
|
|
# 5.5 — Générer la config client (Mac)
|
|
wg genkey | tee ~/mac_private.key | wg pubkey > ~/mac_public.key
|
|
MAC_PRIVKEY=$(cat ~/mac_private.key)
|
|
MAC_PUBKEY=$(cat ~/mac_public.key)
|
|
SERVER_PUBKEY=$(sudo cat /etc/wireguard/server_public.key)
|
|
|
|
# Mettre à jour la config serveur avec la clé publique du Mac
|
|
sudo sed -i "s|<MAC_PUBLIC_KEY>|$MAC_PUBKEY|" /etc/wireguard/wg0.conf
|
|
sudo systemctl restart wg-quick@wg0
|
|
|
|
# Générer le fichier config pour le Mac
|
|
cat > ~/mac-wireguard.conf << EOF
|
|
[Interface]
|
|
PrivateKey = $MAC_PRIVKEY
|
|
Address = 10.0.0.2/24
|
|
DNS = 1.1.1.1
|
|
|
|
[Peer]
|
|
PublicKey = $SERVER_PUBKEY
|
|
AllowedIPs = 10.0.0.0/24
|
|
Endpoint = 76.13.42.203:51820
|
|
PersistentKeepalive = 25
|
|
EOF
|
|
|
|
echo "=== Copier ce fichier sur le Mac ==="
|
|
cat ~/mac-wireguard.conf
|
|
```
|
|
|
|
**Côté Mac** : installer WireGuard (App Store gratuit), importer `mac-wireguard.conf`.
|
|
|
|
---
|
|
|
|
## Phase 6 — Node.js + Python
|
|
|
|
```bash
|
|
# 6.1 — Node.js via nvm
|
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
|
|
source ~/.bashrc
|
|
nvm install 22 && nvm alias default 22
|
|
npm install -g pnpm
|
|
|
|
# 6.2 — Python
|
|
sudo apt install -y python3 python3-venv python3-pip
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 7 — Doppler (secrets)
|
|
|
|
```bash
|
|
# 7.1 — Installer Doppler CLI
|
|
curl -sLf --retry 3 --tlsv1.2 --proto "=https" \
|
|
'https://packages.doppler.com/public/cli/gpg.DE2A7741A397C129.key' | \
|
|
sudo gpg --dearmor -o /usr/share/keyrings/doppler-archive-keyring.gpg
|
|
echo "deb [signed-by=/usr/share/keyrings/doppler-archive-keyring.gpg] \
|
|
https://packages.doppler.com/public/cli/deb/debian any-version main" | \
|
|
sudo tee /etc/apt/sources.list.d/doppler-cli.list
|
|
sudo apt update && sudo apt install -y doppler
|
|
|
|
# 7.2 — Login + setup
|
|
doppler login
|
|
doppler setup --project daemon --config prd
|
|
|
|
# 7.3 — Secrets à ajouter (via dashboard ou CLI) :
|
|
# doppler secrets set ANTHROPIC_API_KEY="sk-ant-..."
|
|
# doppler secrets set NOTION_API_KEY="ntn_..."
|
|
# doppler secrets set OBSIDIAN_API_KEY="..."
|
|
# doppler secrets set GITEA_DB_PASS="<valeur générée en phase 3>"
|
|
# doppler secrets set PERPLEXITY_API_KEY="..."
|
|
# doppler secrets set XAI_API_KEY="..."
|
|
# doppler secrets set GOOGLE_AI_KEY="..."
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 8 — Whisper (transcription audio)
|
|
|
|
```bash
|
|
# 8.1 — Deployer faster-whisper via Docker
|
|
cat >> ~/daemon-infra/docker-compose.yml << 'EOF'
|
|
|
|
whisper:
|
|
image: fedirz/faster-whisper-server:latest-cpu
|
|
container_name: whisper
|
|
ports:
|
|
- "127.0.0.1:8100:8000"
|
|
environment:
|
|
- WHISPER__MODEL=Systran/faster-whisper-medium
|
|
- WHISPER__DEVICE=cpu
|
|
restart: always
|
|
EOF
|
|
|
|
cd ~/daemon-infra && docker compose up -d whisper
|
|
|
|
# 8.2 — Tester
|
|
curl -X POST http://127.0.0.1:8100/v1/audio/transcriptions \
|
|
-F "file=@test.wav" -F "language=fr"
|
|
```
|
|
|
|
> Note : Groq Whisper API = option rapide + pas chère pour le quotidien. Whisper local = fallback gros fichiers / mode offline.
|
|
|
|
---
|
|
|
|
## Phase 9 — n8n (workflows / automatisation)
|
|
|
|
```bash
|
|
cat >> ~/daemon-infra/docker-compose.yml << 'EOF'
|
|
|
|
n8n:
|
|
image: n8nio/n8n:latest
|
|
container_name: n8n
|
|
ports:
|
|
- "127.0.0.1:5678:5678"
|
|
volumes:
|
|
- ./n8n/data:/home/node/.n8n
|
|
environment:
|
|
- N8N_BASIC_AUTH_ACTIVE=true
|
|
- N8N_BASIC_AUTH_USER=jerem
|
|
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
|
|
restart: always
|
|
EOF
|
|
|
|
N8N_PASSWORD=$(openssl rand -base64 16)
|
|
echo "N8N_PASSWORD=$N8N_PASSWORD" >> ~/daemon-infra/.env
|
|
cd ~/daemon-infra && docker compose up -d n8n
|
|
```
|
|
|
|
> Accessible uniquement via VPN (10.0.0.1:5678) ou SSH tunnel.
|
|
|
|
---
|
|
|
|
## Phase 10 — Uptime Kuma (monitoring)
|
|
|
|
```bash
|
|
cat >> ~/daemon-infra/docker-compose.yml << 'EOF'
|
|
|
|
uptime-kuma:
|
|
image: louislam/uptime-kuma:1
|
|
container_name: uptime-kuma
|
|
ports:
|
|
- "127.0.0.1:3001:3001"
|
|
volumes:
|
|
- ./uptime-kuma/data:/app/data
|
|
restart: always
|
|
EOF
|
|
|
|
cd ~/daemon-infra && docker compose up -d uptime-kuma
|
|
```
|
|
|
|
> Dashboard monitoring : vérifier que Gitea, OpenClaw, Whisper, n8n sont up. Alertes via webhook.
|
|
|
|
---
|
|
|
|
## Phase 11 — OpenClaw (le cerveau de DAEMON)
|
|
|
|
> OpenClaw = framework agent open-source, self-hosted. Multi-LLM (Claude, GPT, Gemini, local), multi-chat (WhatsApp, Slack, Telegram, Discord, Signal, iMessage), mémoire persistante, skills extensibles, accès système complet. Site : https://openclaw.ai — Repo : https://github.com/openclaw/openclaw
|
|
|
|
```bash
|
|
# 12.1 — Installer OpenClaw (méthode hackable, pour pouvoir modifier)
|
|
cd ~/daemon-infra
|
|
git clone https://github.com/openclaw/openclaw.git openclaw
|
|
cd openclaw
|
|
npm install
|
|
|
|
# 12.2 — Configurer le SOUL.md (personnalité DAEMON)
|
|
# Copier le soul.md du vault comme system prompt OpenClaw
|
|
cp /home/daemon/vault/_adn/soul.md ./soul.md
|
|
|
|
# 12.3 — Configurer les clés API (via Doppler ou .env)
|
|
# OpenClaw supporte : Anthropic Claude, OpenAI, Google Gemini, modèles locaux
|
|
# Les clés sont injectées via Doppler au runtime
|
|
|
|
# 12.4 — Connecter les MCP Servers
|
|
# Obsidian MCP : accès au vault
|
|
# Notion MCP : accès aux bases Notion
|
|
npm install @notionhq/notion-mcp-server
|
|
|
|
# 12.5 — Configurer les canaux de communication
|
|
# WhatsApp, Slack, Telegram — config dans openclaw selon la doc
|
|
# Priorité : Slack d'abord (le plus simple), WhatsApp ensuite
|
|
|
|
# 12.6 — Service systemd (tourne 24/7)
|
|
sudo tee /etc/systemd/system/openclaw.service << 'EOF'
|
|
[Unit]
|
|
Description=OpenClaw DAEMON
|
|
After=network.target docker.service
|
|
[Service]
|
|
Type=simple
|
|
User=daemon
|
|
WorkingDirectory=/home/daemon/daemon-infra/openclaw
|
|
ExecStart=/usr/bin/doppler run -- node server.js
|
|
Restart=always
|
|
RestartSec=5
|
|
Environment=NODE_ENV=production
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
sudo systemctl daemon-reload && sudo systemctl enable openclaw
|
|
sudo systemctl start openclaw
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 12 — Sync Vault Mac ↔ Gitea ↔ VPS
|
|
|
|
```bash
|
|
# 13.1 — Sur le VPS : cloner le vault depuis Gitea
|
|
cd /home/daemon
|
|
git clone http://127.0.0.1:3000/jerem/daemon-vault.git vault
|
|
cd vault
|
|
git config user.name "DAEMON"
|
|
git config user.email "daemon@jerem.dev"
|
|
|
|
# 13.2 — Script sync auto (cron toutes les 5 min)
|
|
cat > ~/daemon-infra/scripts/vault-sync.sh << 'SCRIPT'
|
|
#!/bin/bash
|
|
cd /home/daemon/vault
|
|
git pull --rebase origin main
|
|
git add -A
|
|
CHANGES=$(git status --porcelain)
|
|
if [ -n "$CHANGES" ]; then
|
|
git commit -m "vault-sync: $(date '+%Y-%m-%d %H:%M')"
|
|
git push origin main
|
|
fi
|
|
SCRIPT
|
|
chmod +x ~/daemon-infra/scripts/vault-sync.sh
|
|
(crontab -l 2>/dev/null; echo "*/5 * * * * ~/daemon-infra/scripts/vault-sync.sh >> ~/daemon-infra/scripts/sync.log 2>&1") | crontab -
|
|
```
|
|
|
|
**Côté Mac** : plugin Obsidian Git (auto-commit + auto-push toutes les 5 min, pull strategy: rebase).
|
|
|
|
```bash
|
|
# Initialisation unique sur le Mac
|
|
cd "/Users/jerems_mac/Library/Mobile Documents/iCloud~md~obsidian/Documents/DAEMON"
|
|
git init
|
|
git remote add origin http://76.13.42.203:3000/jerem/daemon-vault.git
|
|
git add -A && git commit -m "initial vault commit"
|
|
git push -u origin main
|
|
```
|
|
|
|
---
|
|
|
|
## Checklist post-installation
|
|
|
|
- [ ] Tester SSH avec user `daemon` sur port 2222
|
|
- [ ] Vérifier que root SSH est bloqué
|
|
- [ ] Tester VPN WireGuard depuis Mac
|
|
- [ ] Accéder à Gitea, créer repo `daemon-vault`
|
|
- [ ] Push initial du vault depuis Mac
|
|
- [ ] Vérifier sync auto (attendre 5 min, vérifier le log)
|
|
- [ ] Accéder à n8n via VPN
|
|
- [ ] Accéder à Uptime Kuma via VPN
|
|
- [ ] Accéder à Coolify via VPN
|
|
- [ ] Tester transcription Whisper
|
|
- [ ] Migrer les clés API dans Doppler
|
|
- [ ] Configurer les monitors Uptime Kuma (Gitea, OpenClaw, Whisper, n8n)
|
|
|
|
---
|
|
|
|
## ⚠️ Point d'attention : iCloud vs Git
|
|
|
|
Le vault est dans iCloud. iCloud + Git sur le même dossier = conflits possibles.
|
|
|
|
**Recommandation** : déplacer le vault vers `~/Documents/DAEMON` quand Git sync est stable. iCloud n'est plus nécessaire quand Gitea fait le job.
|
|
|
|
---
|
|
|
|
## Après installation — priorités
|
|
|
|
1. Corriger les 6 skills Obsidian (audit du 16 avril)
|
|
2. Déployer les agents Obsidian comme première charge de travail
|
|
3. Premier import Notion → Obsidian
|
|
4. Configurer les routines cron (organizer quotidien, dream hebdo)
|
|
5. Interface Jerem : Slack ou terminal pour parler à DAEMON
|