diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 31f2124..f47a49c 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -7,18 +7,47 @@ on: jobs: deploy: - name: Deploy to 192.168.1.190 - runs-on: ubuntu-latest + name: Build and Deploy + # "docker-host" label = runs directly on the host (192.168.1.190) + runs-on: docker-host steps: - - name: Deploy via SSH - uses: appleboy/ssh-action@v1.2.2 - with: - host: ${{ secrets.DEPLOY_HOST }} - username: ${{ secrets.DEPLOY_USER }} - key: ${{ secrets.DEPLOY_SSH_KEY }} - port: ${{ secrets.DEPLOY_PORT || 22 }} - script_stop: true - command_timeout: 10m - script: | - cd ${{ secrets.DEPLOY_PATH }} - bash scripts/deploy.sh --build + - name: Checkout code + uses: actions/checkout@v4 + + - name: Sync code to deploy directory + run: | + rsync -a --delete \ + --exclude '.git' \ + --exclude 'node_modules' \ + --exclude '.next' \ + --exclude 'memento-note/node_modules' \ + --exclude 'mcp-server/node_modules' \ + ${{ github.workspace }}/ /opt/memento/ + + - name: Build and deploy + working-directory: /opt/memento + run: | + set -e + docker compose build --parallel + docker compose up -d --remove-orphans + + - name: Wait for healthchecks + working-directory: /opt/memento + run: | + echo "Waiting for containers..." + for i in $(seq 1 30); do + UNHEALTHY=$(docker compose ps --format '{{.Status}}' | grep -cv "healthy" || true) + if [ "$UNHEALTHY" -eq 0 ]; then + echo "All containers healthy!" + docker compose ps + exit 0 + fi + sleep 2 + done + echo "Timeout waiting for healthchecks" + docker compose ps + exit 1 + + - name: Cleanup old images + if: always() + run: docker image prune -f diff --git a/DEPLOY.md b/DEPLOY.md index 8ecd38e..5d9fe8a 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -4,9 +4,9 @@ 1. [Architecture](#architecture) 2. [Setup du serveur 192.168.1.190](#setup-serveur) 3. [Installation de Gitea Runner](#gitea-runner) -4. [Configuration CI/CD](#cicd) +4. [CI/CD automatique](#cicd) 5. [Nginx reverse proxy](#nginx) -6. [Checklist de deploiement](#checklist) +6. [Checklist](#checklist) --- @@ -21,81 +21,72 @@ Internet/LAN | └── /mcp ──► [memento-mcp] ── port 3001 ── MCP Server (SSE) | - [postgres] ── port 5432 (interne seulement) + [postgres] ── port 5432 (127.0.0.1 seulement) + +=== Machine 192.168.1.190 === + - Docker + Docker Compose (les 3 conteneurs) + - act_runner (Gitea Runner) --> build + deploy en local + - Nginx reverse proxy + +=== Serveur Gitea (gitea.parsanet.org) === + - Gitea seulement (pas de runner) + - Envoie les events push au runner via API ``` -**Machine 192.168.1.190** (Proxmox Docker container): -- Docker + Docker Compose -- Nginx reverse proxy -- 3 conteneurs: memento-web, memento-mcp, memento-postgres - -**Serveur Gitea** (gitea.parsanet.org): -- Gitea + act_runner -- Se connecte en SSH a 192.168.1.190 pour deployer +Le Runner est installe sur **192.168.1.190** directement. Pas besoin de SSH. --- ## Setup serveur -### 1. Creer l'utilisateur de deploiement sur 192.168.1.190 +### 1. Creer l'utilisateur de deploiement ```bash # Sur 192.168.1.190, en root : - -# Creer l'utilisateur useradd -m -s /bin/bash memento-deploy - -# Donner acces a Docker usermod -aG docker memento-deploy - -# Creer le repertoire projet mkdir -p /opt/memento chown memento-deploy:memento-deploy /opt/memento +``` -# Cloner le repo +### 2. Cloner le repo + +```bash su - memento-deploy cd /opt/memento git clone https://gitea.parsanet.org/sepehr/Momento.git . - -# Configurer git pour le pull automatique git config credential.helper store -# Le premier pull demandera le login, apres ca sera automatique +# Le premier pull demandera les identifiants Gitea ``` -### 2. Generer le .env.docker +### 3. Generer le .env.docker ```bash cd /opt/memento bash scripts/deploy.sh --full ``` -Le script demande interactivement: +Le script demande interactivement : - URL (mettre `http://192.168.1.190` ou `http://notes.parsanet.org`) - Provider AI + cle API - Email (optionnel) -Il genere automatiquement: -- NEXTAUTH_SECRET (random) -- POSTGRES_PASSWORD (random) +Il genere automatiquement NEXTAUTH_SECRET et POSTGRES_PASSWORD. -### 3. Premier deploiement manuel +### 4. Premier deploiement ```bash cd /opt/memento bash scripts/deploy.sh --build -``` - -Verifier: -```bash docker compose ps # Les 3 conteneurs doivent etre "healthy" ``` -### 4. Creer le premier admin +### 5. Creer le premier admin ```bash # S'inscrire sur http://192.168.1.190/register -# Puis promouvoir en admin: +# Puis promouvoir en admin : docker compose exec -T postgres psql -U memento -d memento \ -c "UPDATE \"User\" SET role='ADMIN' WHERE email='VOTRE_EMAIL';" ``` @@ -104,39 +95,69 @@ docker compose exec -T postgres psql -U memento -d memento \ ## Gitea Runner -### Option A: Installer le Runner sur le serveur Gitea +### 1. Activer Actions dans Gitea + +Dans `app.ini` du serveur Gitea : + +```ini +[actions] +ENABLED = true +``` + +Redemarrer Gitea. + +### 2. Recuperer le token d'enregistrement + +Aller sur : **gitea.parsanet.org > Momento > Settings > Actions > Runners > "New Runner"** +Copier le token affiche. + +### 3. Installer act_runner sur 192.168.1.190 ```bash -# Sur le serveur Gitea, en root : +# Sur 192.168.1.190, en root : -# Telecharger act_runner +# Telecharger wget https://gitea.com/gitea/act_runner/releases/latest/download/act_runner-linux-amd64 chmod +x act_runner-linux-amd64 mv act_runner-linux-amd64 /usr/local/bin/act_runner -# Enregistrer le runner -# Aller sur gitea.parsanet.org > Site administration > Actions > Runners > "Create new Runner" -# Copier le token, puis : +# Verifier +act_runner --version + +# Generer la config +mkdir -p /etc/act_runner +act_runner generate-config > /etc/act_runner/config.yaml +``` + +### 4. Enregistrer le runner + +```bash act_runner register \ + --no-interactive \ --instance https://gitea.parsanet.org \ - --token VOTRE_TOKEN \ + --token VOTRE_TOKEN_ICI \ --name memento-deploy \ - --labels ubuntu-latest:docker://node:22-bookworm + --labels "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest,docker-host:host" +``` -# Lancer le runner -act_runner daemon +Les labels sont importants : +- `ubuntu-latest` : pour les jobs dans un conteneur Docker (checkout, etc.) +- `docker-host` : pour les jobs directement sur la machine (acces Docker) -# Ou en tant que service systemd : +### 5. Creer le service systemd + +```bash cat > /etc/systemd/system/gitea-runner.service << 'EOF' [Unit] Description=Gitea Actions Runner -After=network.target +After=network.target docker.service +Requires=docker.service [Service] Type=simple -User=runner -WorkingDirectory=/home/runner -ExecStart=/usr/local/bin/act_runner daemon +User=memento-deploy +WorkingDirectory=/home/memento-deploy +ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml Restart=always RestartSec=5 @@ -147,92 +168,51 @@ EOF systemctl daemon-reload systemctl enable gitea-runner systemctl start gitea-runner +systemctl status gitea-runner ``` -### Option B: Runner en Docker +### 6. Verifier ```bash -# Sur le serveur Gitea : -docker run -d --name gitea-runner \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v act-runner-data:/data \ - -e GITEA_INSTANCE_URL=https://gitea.parsanet.org \ - -e GITEA_RUNNER_REGISTRATION_TOKEN=VOTRE_TOKEN \ - gitea/act_runner:latest +systemctl status gitea-runner +# Doit etre "active (running)" + +# Sur gitea.parsanet.org > Momento > Settings > Actions > Runners +# Le runner "memento-deploy" doit apparaitre avec le label "docker-host" ``` -### Configurer les secrets SSH - -Le Runner doit pouvoir se connecter en SSH a 192.168.1.190. - -```bash -# Sur le serveur Gitea (la ou tourne le runner) : - -# Generer une paire de cles SSH -ssh-keygen -t ed25519 -C "gitea-runner-deploy" -N "" -f /root/.ssh/memento-deploy - -# Afficher la cle publique -cat /root/.ssh/memento-deploy.pub -``` - -```bash -# Sur 192.168.1.190, en tant que memento-deploy : - -mkdir -p ~/.ssh -chmod 700 ~/.ssh -echo "COLLER_LA_CLE_PUBLIQUE_ICI" >> ~/.ssh/authorized_keys -chmod 600 ~/.ssh/authorized_keys -``` - -```bash -# Tester la connexion SSH depuis le serveur Gitea : -ssh -i /root/.ssh/memento-deploy memento-deploy@192.168.1.190 "echo OK" -# Doit afficher "OK" sans demander de mot de passe -``` - -### Ajouter les secrets dans Gitea - -Sur gitea.parsanet.org : -1. Aller dans le repo **Momento** -2. **Settings > Actions > Secrets** -3. Ajouter les secrets suivants : - -| Nom du secret | Valeur | -|---|---| -| `DEPLOY_HOST` | `192.168.1.190` | -| `DEPLOY_USER` | `memento-deploy` | -| `DEPLOY_SSH_KEY` | Le contenu de `/root/.ssh/memento-deploy` (cle privee) | -| `DEPLOY_PATH` | `/opt/memento` | -| `DEPLOY_PORT` | `22` | - --- ## CI/CD -Le workflow est deja dans `.gitea/workflows/deploy.yaml`. +Le workflow est dans `.gitea/workflows/deploy.yaml`. ### Ce qui se passe a chaque push sur `main` : -1. Le Runner recupere le workflow -2. Il se connecte en SSH a 192.168.1.190 -3. Il execute `bash scripts/deploy.sh --build` -4. Le script : - - `git pull origin main` - - `docker compose build --parallel` - - `docker compose up -d` - - Attend les healthchecks - - Initialise la DB si necessaire - - Affiche le status +1. Gitea notifie le Runner sur 192.168.1.190 +2. Le Runner checkout le code +3. `rsync` vers `/opt/memento/` (exclut node_modules, .git, .next) +4. `docker compose build --parallel` +5. `docker compose up -d --remove-orphans` +6. Attend que les 3 conteneurs soient healthy +7. Nettoie les vieilles images -### Verifier que le Runner fonctionne +### Pas de secrets a configurer + +Le `.env.docker` est deja sur le serveur. Le workflow n'a pas besoin de secrets SSH +puisque tout se passe en local sur 192.168.1.190. + +### Tester le CI/CD ```bash -# Sur le serveur Gitea : -act_runner list -# Doit afficher le runner "memento-deploy" +# Faire un push test depuis votre machine : +echo "# test" >> README.md +git add README.md +git commit -m "test: CI/CD deploy" +git push origin main -# Faire un push test sur le repo et verifier dans -# gitea.parsanet.org > Momento > Actions +# Verifier sur gitea.parsanet.org > Momento > Actions +# Le job doit apparaitre et se terminer en succes ``` --- @@ -242,7 +222,6 @@ act_runner list ### Installation ```bash -# Sur 192.168.1.190 : apt install -y nginx ``` @@ -250,14 +229,10 @@ apt install -y nginx ```bash cat > /etc/nginx/sites-available/memento << 'EOF' -# Memento - Nginx reverse proxy server { listen 80; server_name notes.parsanet.org 192.168.1.190; - # Rediriger HTTP vers HTTPS (decommenter quand HTTPS est pret) - # return 301 https://$host$request_uri; - # Next.js app location / { proxy_pass http://127.0.0.1:3000; @@ -271,7 +246,7 @@ server { proxy_read_timeout 86400; } - # MCP Server (SSE) + # MCP Server (SSE - long-lived connections) location /mcp { proxy_pass http://127.0.0.1:3001/mcp; proxy_set_header Host $host; @@ -293,19 +268,16 @@ rm -f /etc/nginx/sites-enabled/default nginx -t && systemctl reload nginx ``` -### HTTPS avec Let's Encrypt (optionnel, plus tard) +### HTTPS (plus tard) ```bash apt install -y certbot python3-certbot-nginx certbot --nginx -d notes.parsanet.org -``` -Puis mettre a jour `NEXTAUTH_URL` dans `.env.docker`: -```bash -# Sur 192.168.1.190 : +# Puis mettre a jour NEXTAUTH_URL : cd /opt/memento nano .env.docker -# Changer NEXTAUTH_URL="https://notes.parsanet.org" +# Changer : NEXTAUTH_URL="https://notes.parsanet.org" docker compose restart memento-note ``` @@ -313,46 +285,27 @@ docker compose restart memento-note ## Checklist -### Premier deploiement (une seule fois) +### Premier deploiement -- [ ] Creer `memento-deploy` sur 192.168.1.190 avec acces Docker +- [ ] Creer `memento-deploy` sur 192.168.1.190 - [ ] Cloner le repo dans `/opt/memento` -- [ ] Executer `bash scripts/deploy.sh --full` -- [ ] Verifier les 3 conteneurs healthy -- [ ] S'inscrire sur l'app -- [ ] Promouvoir le premier utilisateur en ADMIN +- [ ] `bash scripts/deploy.sh --full` +- [ ] 3 conteneurs healthy +- [ ] S'inscrire, puis promouvoir en ADMIN via SQL - [ ] Configurer Nginx ### CI/CD (une seule fois) -- [ ] Installer `act_runner` sur le serveur Gitea -- [ ] Enregistrer le runner dans Gitea -- [ ] Generer la cle SSH et la copier sur 192.168.1.190 -- [ ] Tester la connexion SSH -- [ ] Ajouter les 5 secrets dans Gitea -- [ ] Faire un push test et verifier dans Actions +- [ ] Activer Actions dans Gitea (`app.ini`) +- [ ] Installer `act_runner` sur 192.168.1.190 +- [ ] Enregistrer avec le token Gitea +- [ ] Creer le service systemd +- [ ] Verifier le runner apparait dans Gitea +- [ ] Push test > verifier dans Actions ### Apres chaque push sur main (automatique) - [ ] Le Runner detecte le push -- [ ] SSH vers 192.168.1.190 -- [ ] git pull +- [ ] rsync vers /opt/memento - [ ] docker compose build + up - [ ] Conteneurs healthy - ---- - -## Variables d'environnement requises dans .env.docker - -| Variable | Description | Exemple | -|---|---|---| -| `NEXTAUTH_URL` | URL publique de l'app | `http://192.168.1.190` | -| `NEXTAUTH_SECRET` | Cle secrete (auto-genere) | random base64 | -| `ALLOW_REGISTRATION` | Inscription publique | `true` ou `false` | -| `POSTGRES_DB` | Nom de la base | `memento` | -| `POSTGRES_USER` | Utilisateur Postgres | `memento` | -| `POSTGRES_PASSWORD` | Mot de passe (auto-genere) | random hex | -| `MCP_MODE` | Mode MCP | `sse` | -| `AI_PROVIDER_TAGS` | Provider pour les tags | `openrouter` | -| `CUSTOM_OPENAI_API_KEY` | Cle API (si openrouter) | `sk-or-v1-...` | -| `CUSTOM_OPENAI_BASE_URL` | URL du provider | `https://openrouter.ai/api/v1` |