Jelajahi Sumber

chore: setup standalone deploy infrastructure

unknown 2 hari lalu
induk
melakukan
60afc342de
7 mengubah file dengan 90 tambahan dan 64 penghapusan
  1. 0 1
      backend/routers/__init__.py
  2. 5 27
      backend/routers/admin.py
  3. 8 31
      deploy.cmd
  4. 29 0
      deploy_listener.py
  5. 8 5
      nginx.conf
  6. 12 0
      radionica-deploy.service
  7. 28 0
      server_update.sh

+ 0 - 1
backend/routers/__init__.py

@@ -6,4 +6,3 @@ from . import portfolio
 from . import files
 from . import chat
 from . import blog
-from . import admin

+ 5 - 27
backend/routers/admin.py

@@ -1,8 +1,7 @@
+from fastapi import APIRouter, Depends, HTTPException, Query
+from typing import List, Optional
 import db
 import auth_utils
-import subprocess
-import os
-from fastapi import APIRouter, Depends, HTTPException, Query, BackgroundTasks, Request
 from dependencies import require_admin
 
 router = APIRouter(prefix="/admin", tags=["admin"])
@@ -41,30 +40,9 @@ async def get_audit_logs(
     else:
         total = db.execute_query(count_query)
         
+    return {
+        "logs": logs,
+        "total": total[0]['total'],
         "page": page,
         "size": size
     }
-
-def run_deploy():
-    """Фоновая задача для обновления сайта"""
-    try:
-        # Путь к корню проекта
-        root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-        # Выполняем цепочку команд
-        cmd = f"cd {root_dir} && git pull && npm install && ./build_frontend.sh && sudo systemctl restart radionica-backend"
-        subprocess.run(cmd, shell=True, check=True, capture_output=True)
-        print("✅ Auto-deploy finished successfully")
-    except Exception as e:
-        print(f"❌ Auto-deploy failed: {e}")
-
-@router.post("/webhook/deploy")
-async def deploy_webhook(
-    secret: str, 
-    background_tasks: BackgroundTasks
-):
-    # Секретный ключ для защиты от спама
-    if secret != "NY9B9VLifDC9ehZ":
-        raise HTTPException(status_code=403, detail="Invalid secret")
-    
-    background_tasks.add_task(run_deploy)
-    return {"message": "Deployment triggered"}

+ 8 - 31
deploy.cmd

@@ -4,40 +4,17 @@ setlocal enabledelayedexpansion
 :: --- НАСТРОЙКИ ---
 set REMOTE_HOST=148.230.71.134
 set REMOTE_USER=root
-set REMOTE_DIR=/var/www/radionica3d
-set CHOWN_USER=www-data
 :: -----------------
 
-echo [1/5] 🚀 Nachinaem NADEZHNYY deploy (TAR + SCP)...
+echo [1/3] 🚀 Otprafka koda v Git...
+git add .
+git commit -m "auto deploy"
+git push origin master
+if %ERRORLEVEL% neq 0 (echo Push failed! & exit /b %ERRORLEVEL%)
 
-:: 1. Сборка фронтенда
-echo [2/5] 🔨 Sborka frontenda...
-python scripts/manage_locales.py split
-call npm run build
-if %ERRORLEVEL% neq 0 (echo Build failed! & exit /b %ERRORLEVEL%)
-
-:: 2. Упаковка в архив (пакуем только то, что нужно)
-echo [3/5] 📦 Upakovka proyekta...
-:: Удаляем старый архив если остался
-if exist deploy.tar.gz del deploy.tar.gz
-:: Пакуем dist, backend (без venv) и конфиги
-tar -czf deploy.tar.gz dist/ backend/ nginx.conf radionica-backend.service --exclude=backend/venv --exclude=backend/__pycache__ --exclude=backend/uploads
-if %ERRORLEVEL% neq 0 (echo Archiving failed! & exit /b %ERRORLEVEL%)
-
-:: 3. Отправка на сервер
-echo [4/5] 📨 Otprafka arkhiva...
-scp deploy.tar.gz %REMOTE_USER%@%REMOTE_HOST%:~/
-if %ERRORLEVEL% neq 0 (echo Upload failed! & exit /b %ERRORLEVEL%)
-
-:: 4. Команды на сервере
-echo [5/5] ⚙️ Nastroyka servera...
-ssh %REMOTE_USER%@%REMOTE_HOST% "mkdir -p ~/tmp_deploy_dir && tar -xzf ~/deploy.tar.gz -C ~/tmp_deploy_dir && sudo mkdir -p %REMOTE_DIR%/html && sudo mkdir -p %REMOTE_DIR%/backend && sudo cp -r ~/tmp_deploy_dir/dist/* %REMOTE_DIR%/html/ && cd %REMOTE_DIR%/backend && ([ -d venv ] || python3 -m venv venv) && source venv/bin/activate && (cmp -s ~/tmp_deploy_dir/backend/requirements.txt requirements.txt || (cp ~/tmp_deploy_dir/backend/requirements.txt requirements.txt && pip install -r requirements.txt && pip install gunicorn uvicorn)) && sudo cp -r ~/tmp_deploy_dir/backend/* . && sudo cp ~/tmp_deploy_dir/nginx.conf /etc/nginx/sites-available/radionica3d && sudo ln -sf /etc/nginx/sites-available/radionica3d /etc/nginx/sites-enabled/ && (sudo nginx -t && sudo systemctl restart nginx) && sudo cp ~/tmp_deploy_dir/radionica-backend.service /etc/systemd/system/ && sudo systemctl daemon-reload && sudo systemctl restart radionica-backend && sudo chown -R %CHOWN_USER%:%CHOWN_USER% %REMOTE_DIR% && rm ~/deploy.tar.gz && rm -rf ~/tmp_deploy_dir"
-
-if %ERRORLEVEL% neq 0 (echo Remote commands failed! & exit /b %ERRORLEVEL%)
-
-:: 5. Очистка локально
-del deploy.tar.gz
+echo [2/3] ⚙️ Zapusk sborki na servere...
+ssh %REMOTE_USER%@%REMOTE_HOST% "cd /var/www/radionica3d && git pull && npm install && ./build_frontend.sh && source backend/venv/bin/activate && pip install -r backend/requirements.txt && sudo systemctl restart radionica-backend && sudo systemctl restart nginx && sudo chown -R www-data:www-data /var/www/radionica3d"
 
 echo.
-echo 🎉 DEPLOY USPESHNO ZAVERSHEN!
+echo 🎉 DEPLOY CHEREZ GIT USPESHNO ZAVERSHEN!
 pause

+ 29 - 0
deploy_listener.py

@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+from http.server import BaseHTTPRequestHandler, HTTPServer
+import subprocess
+import os
+import sys
+
+# Секретный ключ (соответствует тому, что в вебхуке)
+SECRET = "NY9B9VLifDC9ehZ"
+
+class WebhookHandler(BaseHTTPRequestHandler):
+    def do_POST(self):
+        # Проверяем секрет в URL
+        if f"secret={SECRET}" in self.path:
+            self.send_response(200)
+            self.end_headers()
+            self.wfile.write(b"Deployment triggered successfully\n")
+            
+            # Запускаем скрипт обновления в фоне
+            print(">>> Received webhook, starting deployment...")
+            subprocess.Popen(["/bin/bash", "/var/www/radionica3d/server_update.sh"])
+        else:
+            self.send_response(403)
+            self.end_headers()
+            self.wfile.write(b"Forbidden: Invalid secret\n")
+
+if __name__ == "__main__":
+    print("Deploy listener starting on port 9000...")
+    httpd = HTTPServer(('127.0.0.1', 9000), WebhookHandler)
+    httpd.serve_forever()

+ 8 - 5
nginx.conf

@@ -15,12 +15,15 @@ server {
 
     # Proxy API requests to backend
     location /api/ {
-        proxy_pass http://backend:8000/;
-        proxy_http_version 1.1;
-        proxy_set_header Upgrade $http_upgrade;
-        proxy_set_header Connection 'upgrade';
+        proxy_pass http://localhost:8000/;
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+    }
+
+    # Standalone Deploy Webhook
+    location /deploy-webhook {
+        proxy_pass http://127.0.0.1:9000;
         proxy_set_header Host $host;
-        proxy_cache_bypass $http_upgrade;
     }
 
     # WebSocket requests

+ 12 - 0
radionica-deploy.service

@@ -0,0 +1,12 @@
+[Unit]
+Description=Radionica3D Deploy Webhook Listener
+After=network.target
+
+[Service]
+User=root
+WorkingDirectory=/var/www/radionica3d
+ExecStart=/usr/bin/python3 /var/www/radionica3d/deploy_listener.py
+Restart=always
+
+[Install]
+WantedBy=multi-user.target

+ 28 - 0
server_update.sh

@@ -0,0 +1,28 @@
+#!/bin/bash
+# Скрипт автоматического обновления сайта
+PROJECT_DIR="/var/www/radionica3d"
+
+echo "==== DEPLOY STARTING: $(date) ===="
+cd $PROJECT_DIR
+
+# 1. Забираем код
+echo "git pull..."
+git pull origin master
+
+# 2. Собираем фронтенд
+echo "building frontend..."
+npm install
+./build_frontend.sh
+
+# 3. Обновляем бэкенд
+echo "updating backend..."
+source backend/venv/bin/activate
+pip install -r backend/requirements.txt
+
+# 4. Перезапуск
+echo "restarting services..."
+sudo systemctl restart radionica-backend
+sudo systemctl restart nginx
+sudo chown -R www-data:www-data $PROJECT_DIR
+
+echo "==== DEPLOY FINISHED: $(date) ===="