Files
pwa/DEPLOYMENT_RUNBOOK.md

10 KiB

Noya — Production Deployment Runbook (راهنمای جامع استقرار ایزوله)

این سند راهنمای عملیاتی و گام‌به‌گام برای استقرار ایمن و کاملاً ایزوله پروژه Noya روی سرور جدید است. این فرآیند به گونه‌ای طراحی شده که هیچ تداخلی با سایر پروژه‌ها، پورت‌ها، کانتینرها و دیتابیس‌های موجود روی سرور ایجاد نکند و تا زمان تأیید نهایی، هیچ نیازی به تغییر در رکوردهای DNS دامنه ندارد.


۱. پیش‌نیازها و ارزیابی سرور جدید (Server Preflight)

پیش از انتقال یا اجرای هر فایلی، دستورات زیر را روی سرور جدید اجرا کنید:

# ۱. بررسی فضای دیسک و حافظه رم (حداقل ۱۰ گیگابایت دیسک و ۲ گیگابایت رم آزاد پیشنهاد می‌شود)
df -h /
free -m

# ۲. بررسی معماری پردازنده و فلگ SSE4.2 (جهت تعیین نسخه MySQL)
lscpu | grep -E "Model name|Flags|sse4_2"

# ۳. بررسی پورت‌های در حال استفاده (جهت اطمینان از آزاد بودن پورت ۳۸۰۸۰ یا انتخاب پورت دیگر)
sudo ss -tulpn | grep 38080

# ۴. بررسی کانتینرها و شبکه‌های فعال داکر
docker ps --format "table {{.Names}}\t{{.Ports}}\t{{.Status}}"
docker network ls

# ۵. بررسی وضعیت Reverse Proxy فعال سرور (Nginx، Caddy، Traefik یا NPM)
ps aux | grep -E 'nginx|caddy|traefik'

۲. روش ساخت (Build) و بسته‌بندی Imageها در سیستم محلی

با توجه به محدودیت‌های احتمالی دانلود پکیج‌ها و باینری‌های Prisma روی سرورهای واقع در ایران، روش پیشنهادی و پایدار، ساخت محلی Imageها و انتقال آن‌ها به صورت فایل فشرده است:

# در سیستم محلی (پوشه ریشه پروژه E:\P_W_A):

# الف) ساخت ایمیج فرانت‌اند برای معماری لینوکس x86_64
docker build --platform linux/amd64 -t noya-frontend:latest .

# ب) ساخت ایمیج بک‌اند برای معماری لینوکس x86_64
docker build --platform linux/amd64 -t noya-backend:latest ./backend

# ج) خروجی و فشرده‌سازی ایمیج‌ها به فرمت tar.gz
docker save noya-frontend:latest | gzip > noya-frontend.tar.gz
docker save noya-backend:latest | gzip > noya-backend.tar.gz

نکته: در صورتی که پردازنده سرور جدید ARM64 باشد (مانند سرورهای Hetzner CAX)، در دستورات فوق مقدار --platform linux/arm64 قرار دهید.


۳. انتقال فایل‌ها به سرور جدید

فولدر اختصاصی برای پروژه در مسیر استاندارد سرور (مثلاً /opt/noya) ایجاد کنید:

# روی سرور جدید:
sudo mkdir -p /opt/noya/backend
sudo chown -R $USER:$USER /opt/noya

سپس از سیستم محلی، فایل‌های موردنیاز را با scp منتقل کنید:

# انتقال ایمیج‌های ساخته‌شده:
scp noya-frontend.tar.gz noya-backend.tar.gz user@NEW_SERVER_IP:/opt/noya/

# انتقال فایل کامپوز و نمونه‌های کانفیگ:
scp docker-compose.prod.yml user@NEW_SERVER_IP:/opt/noya/
scp .env.production.example user@NEW_SERVER_IP:/opt/noya/.env
scp .env.mysql.example user@NEW_SERVER_IP:/opt/noya/.env.mysql
scp backend/.env.production.example user@NEW_SERVER_IP:/opt/noya/backend/.env

۴. بارگذاری ایمیج‌ها و تنظیم متغیرهای محیطی روی سرور

وارد سرور شوید و مراحل زیر را انجام دهید:

۴.۱. لود کردن ایمیج‌ها در Docker سرور

cd /opt/noya
docker load < noya-frontend.tar.gz
docker load < noya-backend.tar.gz

۴.۲. تنظیم فایل‌های محیطی محرمانه

فایل‌های .env را با مقادیر واقعی و امن ویرایش کنید:

  1. فایل دیتابیس (/opt/noya/.env.mysql):

    MYSQL_ROOT_PASSWORD=your_generated_secure_root_password_32char
    MYSQL_DATABASE=noya_db
    MYSQL_USER=noya_user
    MYSQL_PASSWORD=your_generated_secure_user_password_32char
    
  2. فایل اصلی کامپوز (/opt/noya/.env):

    NOYA_WEB_PORT=38080
    NOYA_IMAGE_TAG=latest
    # در صورت پشتیبانی CPU از SSE4.2 می‌توانید mysql:8.0 بگذارید، در غیر این صورت mysql:5.7
    NOYA_MYSQL_IMAGE=mysql:5.7
    
  3. فایل بک‌اند (/opt/noya/backend/.env):

    NODE_ENV=production
    PORT=3001
    HOST=0.0.0.0
    # توجه به رمز عبور: اگر رمز حاوی کاراکترهای خاص است باید URL-encoded باشد.
    # پیشنهاد: استفاده از رمز صرفاً الفبانومریک (A-Z, a-z, 0-9) با طول ۳۲ حرف.
    DATABASE_URL=mysql://noya_user:your_generated_secure_user_password_32char@noya-mysql:3306/noya_db
    LOG_LEVEL=info
    CORS_ORIGIN=https://your-domain.com
    TRUST_PROXY=true
    AUTH_SESSION_TTL_HOURS=168
    ADMIN_EMAILS=admin@your-domain.com
    OPENAI_API_KEY=your_production_gapgpt_or_openai_api_key
    OPENAI_BASE_URL=https://api.gapgpt.app/v1
    OPENAI_MODEL=gpt-4o-mini
    

۵. راه‌اندازی سرویس‌ها

cd /opt/noya
docker compose -f docker-compose.prod.yml up -d

بررسی وضعیت کانتینرها:

docker compose -f docker-compose.prod.yml ps

کانتینرهای زیر باید در حالت Up (و برای MySQL در وضعیت healthy) باشند:

  • noya-mysql
  • noya-backend
  • noya-frontend

۶. تست و اعتبارسنجی پیش از تغییر DNS (Zero-Downtime Verification)

۶.۱. تست داخلی سرور (Localhost Health)

# بررسی سلامت وب فرانت‌اند
curl -I http://127.0.0.1:38080/health
# پاسخ باید HTTP 200 با متن healthy باشد

# بررسی سلامت بک‌اند و ارتباط موفق با MySQL (اجرای موفق مایگریشن‌ها و سید)
curl -s http://127.0.0.1:38080/api/backend/ready
# خروجی باید شامل status: "ready" و database: "ok" باشد:
# {"success":true,"data":{"status":"ready","checks":{"database":"ok"}}}

۶.۲. اتصال به Reverse Proxy موجود سرور

یک VirtualHost مستقل برای دامنه نویا به Nginx اصلی سرور اضافه کنید (مثلاً /etc/nginx/sites-available/noya.conf):

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://127.0.0.1:38080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 10s;
        proxy_read_timeout 180s;
        proxy_send_timeout 180s;
    }
}

سپس فعال‌سازی و ریلود:

sudo ln -s /etc/nginx/sites-available/noya.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

۶.۳. تست با Override کلاینت (بدون دستکاری DNS)

در کامپیوتر خودتان، فایل hosts را باز کنید:

  • ویندوز: C:\Windows\System32\drivers\etc\hosts
  • لینوکس / مک: /etc/hosts

خط زیر را اضافه کنید:

NEW_SERVER_IP    your-domain.com

اکنون مرورگر خود را در حالت Private/Incognito باز کرده و آدرس http://your-domain.com را بررسی کنید:

  1. ثبت نام کاربر تستی جدید.
  2. ارسال پیام چت و دریافت پاسخ استریم هوش مصنوعی.
  3. بررسی باز شدن جلسات آموزشی.
  4. بررسی عدم بروز هرگونه خطای CORS یا دیتابیس در کنسول مرورگر (F12).

۷. مشاهده و بررسی لاگ‌ها (Log Inspection)

# لاگ زنده تمام سرویس‌های نویا
docker compose -f docker-compose.prod.yml logs -f --tail=100

# لاگ اختصاصی بک‌اند
docker compose -f docker-compose.prod.yml logs -f noya-backend

# لاگ اختصاصی دیتابیس
docker compose -f docker-compose.prod.yml logs -f noya-mysql

# لاگ اختصاصی فرانت‌اند
docker compose -f docker-compose.prod.yml logs -f noya-frontend

۸. فعال‌سازی نهایی دامنه (Final Cutover)

پس از تأیید کامل تست مرحله ۶:

  1. صدور گواهی SSL (Let's Encrypt / Certbot) روی سرور جدید:
    sudo certbot --nginx -d your-domain.com
    
  2. حذف خط تستی اضافه شده به فایل hosts سیستم محلی شما.
  3. ورود به پنل مدیریت دامنه (Cloudflare، ابرآروان یا کنترل‌پنل دامنه) و تغییر رکورد A به NEW_SERVER_IP.

۹. برنامه بازگشت اضطراری (Rollback Plan)

در صورت بروز هرگونه مشکل یا ناپایداری غیرمنتظره پس از اتصال:

  1. بازگشت فوری DNS: رکورد A در پنل DNS به IP سرور قبلی بازگردانده شود (ظرف چند دقیقه اعمال می‌شود).
  2. توقف امن سرویس‌های نویا روی سرور جدید:
    cd /opt/noya
    docker compose -f docker-compose.prod.yml stop
    
    (داده‌های ثبت‌شده در Volume noya_mysql_data بدون آسیب حفظ می‌مانند).
  3. غیرفعال‌سازی کانفیگ در Reverse Proxy سرور جدید:
    sudo rm -f /etc/nginx/sites-enabled/noya.conf
    sudo nginx -t && sudo systemctl reload nginx
    
    با این کار، سرور جدید دقیقاً به وضعیت پاک و اولیه خود قبل از استقرار نویا بازمی‌گردد.