name: Deploy to Production on: push: branches: - main workflow_dispatch: jobs: deploy: name: Build and Deploy runs-on: ubuntu-24.04 steps: - name: Setup SSH run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan -H 192.168.1.190 >> ~/.ssh/known_hosts - name: Update .env.docker from Gitea vars & secrets env: # ── Auth ────────────────────────────────────────── APP_URL: ${{ vars.APP_URL }} NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }} ADMIN_EMAIL: ${{ vars.ADMIN_EMAIL }} ALLOW_REGISTRATION: ${{ vars.ALLOW_REGISTRATION }} # ── Database ────────────────────────────────────── POSTGRES_USER: ${{ vars.POSTGRES_USER }} POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} POSTGRES_DB: ${{ vars.POSTGRES_DB }} POSTGRES_PORT: ${{ vars.POSTGRES_PORT }} # ── AI Provider ─────────────────────────────────── AI_PROVIDER_TAGS: ${{ vars.AI_PROVIDER_TAGS }} AI_MODEL_TAGS: ${{ vars.AI_MODEL_TAGS }} AI_PROVIDER_EMBEDDING: ${{ vars.AI_PROVIDER_EMBEDDING }} AI_MODEL_EMBEDDING: ${{ vars.AI_MODEL_EMBEDDING }} AI_PROVIDER_CHAT: ${{ vars.AI_PROVIDER_CHAT }} AI_MODEL_CHAT: ${{ vars.AI_MODEL_CHAT }} CUSTOM_OPENAI_BASE_URL: ${{ vars.CUSTOM_OPENAI_BASE_URL }} CUSTOM_OPENAI_API_KEY: ${{ secrets.CUSTOM_OPENAI_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} OLLAMA_BASE_URL: ${{ vars.OLLAMA_BASE_URL }} # ── Email ───────────────────────────────────────── EMAIL_PROVIDER: ${{ vars.EMAIL_PROVIDER }} SMTP_FROM: ${{ vars.SMTP_FROM }} RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }} SMTP_HOST: ${{ vars.SMTP_HOST }} SMTP_PORT: ${{ vars.SMTP_PORT }} SMTP_USER: ${{ vars.SMTP_USER }} SMTP_PASS: ${{ secrets.SMTP_PASS }} SMTP_SECURE: ${{ vars.SMTP_SECURE }} SMTP_IGNORE_CERT: ${{ vars.SMTP_IGNORE_CERT }} # ── MCP ─────────────────────────────────────────── MCP_MODE: ${{ vars.MCP_MODE }} MCP_PORT: ${{ vars.MCP_PORT }} # ── Tools ───────────────────────────────────────── WEB_SEARCH_PROVIDER: ${{ vars.WEB_SEARCH_PROVIDER }} SEARXNG_URL: ${{ vars.SEARXNG_URL }} BRAVE_SEARCH_API_KEY: ${{ secrets.BRAVE_SEARCH_API_KEY }} JINA_API_KEY: ${{ secrets.JINA_API_KEY }} run: | ssh root@192.168.1.190 bash << 'ENDSSH' ENV_FILE="/opt/memento/.env.docker" # Crée le fichier s'il n'existe pas touch "$ENV_FILE" # Fonction : supprime toutes les occurrences de la clé puis ajoute la nouvelle valeur upsert() { local key="$1" val="$2" [ -z "$val" ] && return # Supprimer toutes les lignes existantes (évite les doublons) sed -i "/^[[:space:]]*${key}=/d" "$ENV_FILE" echo "${key}=\"${val}\"" >> "$ENV_FILE" } upsert NEXTAUTH_URL "$APP_URL" upsert NEXTAUTH_SECRET "$NEXTAUTH_SECRET" upsert ADMIN_EMAIL "$ADMIN_EMAIL" upsert ALLOW_REGISTRATION "$ALLOW_REGISTRATION" upsert POSTGRES_USER "$POSTGRES_USER" upsert POSTGRES_PASSWORD "$POSTGRES_PASSWORD" upsert POSTGRES_DB "$POSTGRES_DB" upsert POSTGRES_PORT "$POSTGRES_PORT" upsert AI_PROVIDER_TAGS "$AI_PROVIDER_TAGS" upsert AI_MODEL_TAGS "$AI_MODEL_TAGS" upsert AI_PROVIDER_EMBEDDING "$AI_PROVIDER_EMBEDDING" upsert AI_MODEL_EMBEDDING "$AI_MODEL_EMBEDDING" upsert AI_PROVIDER_CHAT "$AI_PROVIDER_CHAT" upsert AI_MODEL_CHAT "$AI_MODEL_CHAT" upsert CUSTOM_OPENAI_BASE_URL "$CUSTOM_OPENAI_BASE_URL" upsert CUSTOM_OPENAI_API_KEY "$CUSTOM_OPENAI_API_KEY" upsert OPENAI_API_KEY "$OPENAI_API_KEY" upsert OLLAMA_BASE_URL "$OLLAMA_BASE_URL" upsert EMAIL_PROVIDER "$EMAIL_PROVIDER" upsert SMTP_FROM "$SMTP_FROM" upsert RESEND_API_KEY "$RESEND_API_KEY" upsert SMTP_HOST "$SMTP_HOST" upsert SMTP_PORT "$SMTP_PORT" upsert SMTP_USER "$SMTP_USER" upsert SMTP_PASS "$SMTP_PASS" upsert SMTP_SECURE "$SMTP_SECURE" upsert SMTP_IGNORE_CERT "$SMTP_IGNORE_CERT" upsert MCP_MODE "$MCP_MODE" upsert MCP_PORT "$MCP_PORT" upsert WEB_SEARCH_PROVIDER "$WEB_SEARCH_PROVIDER" upsert SEARXNG_URL "$SEARXNG_URL" upsert BRAVE_SEARCH_API_KEY "$BRAVE_SEARCH_API_KEY" upsert JINA_API_KEY "$JINA_API_KEY" echo ".env.docker updated" # Redémarre les containers pour appliquer les nouvelles vars d'env cd /opt/memento && docker compose up -d --force-recreate memento-note ENDSSH - name: Deploy via SSH run: | ssh root@192.168.1.190 << 'ENDSSH' set -e cd /opt/memento echo "=== Git pull ===" git config --global --add safe.directory /opt/memento git pull origin main echo "=== Building ===" docker compose build memento-note docker compose build mcp-server echo "=== Starting ===" docker compose up -d --remove-orphans docker compose ps ENDSSH - name: Wait for app to be healthy run: | echo "Waiting up to 180s for http://192.168.1.190 ..." for i in $(seq 1 36); do CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 -L http://192.168.1.190/ || echo "000") if [ "$CODE" != "000" ] && [ "$CODE" -lt 500 ]; then echo "✅ App OK (HTTP $CODE) after $((i * 5))s" exit 0 fi echo " [$((i * 5))s] HTTP $CODE" sleep 5 done echo "Timeout! Derniers logs :" ssh root@192.168.1.190 "docker logs memento-web --tail=50" exit 1 - name: Cleanup if: always() run: ssh root@192.168.1.190 "docker image prune -f" || true