From bd329f83aef26f46979e72fe17a137556ec6710b Mon Sep 17 00:00:00 2001 From: Zareian Date: Sat, 17 Oct 2026 19:06:04 +0330 Subject: [PATCH] Dedicated server 78.38.35.216: state and cut-over order in docs, CLAUDE.md entry, password snippet for two Password lines, archive-app-log.sh finds its project dir Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 9 +++++- docs/operations.md | 52 ++++++++++++++++++++++++++++++++++ ops/applogs/archive-app-log.sh | 5 ++-- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a02cdc5..04f6330 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -67,6 +67,12 @@ request to the server admin, not something to fix. and the `zareian-pg-*` / `zareian-applog-pull` units. It also runs other teams' services and its own `postgresql@14-main`, which we never use. +**`78.38.35.216` (`tadrisino`, new dedicated VM, not yet serving users)**, account `zareian` (sudo): the whole +machine is ours. The app runs as the non-sudo user `mathapp` under `/home/mathapp/`; same unit names as on 249. +Password is the `Password` line after `NewServer` in the password file. State and the cut-over order: +`docs/operations.md` «سرورِ اختصاصیِ جدید». Until cut-over, 249 stays the live server and every rule below applies +there unchanged; on 216, rules 1, 5, 6, 8 and 10 still apply. + ### Rules (not negotiable) 1. **Read-only first.** Before changing anything, look: `systemctl status`, `ls`, `git -C … log -1`, @@ -114,7 +120,8 @@ session. Take only the password line, everything after the first `: ` (stripping once sent the whole line and SSH refused it): ```bash -sed -n '/^Password/{s/^[^:]*: *//;p;}' ~/Desktop/'رمز سرور.txt' > "$SCRATCH/.pw" && chmod 600 "$SCRATCH/.pw" +sed -n '/^Password/{s/^[^:]*: *//;p;q;}' ~/Desktop/'رمز سرور.txt' | tr -d '\r\n' > "$SCRATCH/.pw" && chmod 600 "$SCRATCH/.pw" # 249/247 (first Password line) +awk '/^NewServer/{f=1;next} f && /^Password/{sub(/^[^:]*: */,"");printf "%s",$0;exit}' ~/Desktop/'رمز سرور.txt' > "$SCRATCH/.pwn" && chmod 600 "$SCRATCH/.pwn" # 216 sshpass -f "$SCRATCH/.pw" ssh administrator@78.38.35.249 '' sshpass -f "$SCRATCH/.pw" ssh administrator@78.38.35.249 'sudo -S -p "" ' < "$SCRATCH/.pw" rm -P "$SCRATCH/.pw" # as soon as the work is done (macOS has no shred); recreate it next time diff --git a/docs/operations.md b/docs/operations.md index 33a33d2..a87a386 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -382,6 +382,58 @@ the servers»): - سنجیده (۲۰۲۶-۱۰-۱۳): اپ در Chrome، بی‌ورود و با ورود، همه‌ی تب‌ها و آزمونِ یک جزیره، بی هیچ خطای CSP. **نسنجیده:** اپِ اندروید (WebView همان CSP را می‌گیرد) و صفحه‌ی `pay.html` تا درگاه. +## سرورِ اختصاصیِ جدید (`78.38.35.216`): آماده، هنوز سوئیچ نشده + +اپ به یک ماشینِ مجازیِ اختصاصی منتقل می‌شود. کاربران هنوز از ۲۴۹ سرو می‌شوند؛ ArvanCloud هنوز به ۲۴۹ اشاره می‌کند. + +| | | +|---|---| +| ماشین | VMware، Ubuntu 24.04، ۸ هسته، ۱۲ گیگ رم، دیسکِ ۹۷ گیگ؛ hostname `tadrisino`، IPِ داخلی `192.168.200.163` (۲۴۹ = `.164`)، IPِ خروجی `78.38.35.228` | +| ورود | `ssh zareian@78.38.35.216` (sudo). `temp` حسابِ موقتِ ادمینِ شبکه است و حذف می‌شود. ورودِ root بسته، `AllowUsers zareian temp`، fail2ban روی SSH | +| اپ | کاربرِ بی‌sudoِ `mathapp`؛ `/home/mathapp/mathapp-v2` و `/home/mathapp/mathapp_frontend_new` | +| سرویس‌ها | `zareian-mathapp` (= `gunicorn-mathapp`، با `RuntimeDirectory`)، `zareian-redis` (6390)، `postgresql@16-zareian` (5440)، `nginx`، `zareian-applog-archive.timer` | +| رمزها | رمزِ Postgres و Redis روی این سرور تازه ساخته شده (`.pg_password`، `.redis_password` کنارِ `.env`)، نه کپیِ ۲۴۹ | +| فایروال | ufw فقط 22/80/443. فایروالِ شبکه‌ی شرکت 443ِ ورودی را هنوز می‌بندد (80 باز است) | +| بسته‌ها | apt از `mirror.arvancloud.ir`، pip از `mirror-pypi.runflare.com` (`~mathapp/.config/pip/pip.conf`)، npm از `mirror-npm.runflare.com`؛ `files.pythonhosted.org` و `registry.npmjs.org` از این سرور بسته‌اند | + +سنجیده: `/api/health` با همه‌ی جزئیات ok (فقط هشدارِ نبودنِ اسلاتِ بکاپ)، Qdrant از این سرور وصل، فرانت ۲۰۰، ریبوت و +بالا آمدنِ خودکارِ همه‌ی سرویس‌ها، درخواستِ مستقیم به IP ۴۰۳ (nginx IPِ واقعی را می‌بیند). نسنجیده: هیچ درخواستی از مسیرِ ArvanCloud، +پیامک، پرداخت و تیوتورِ زنده. + +**سوئیچ (ترتیب):** ۱) 443ِ ورودی باز شود. ۲) روی ۲۴۹ `zareian-mathapp` متوقف (پیامِ نگه‌داری در ArvanCloud)، `pg_dump -Fc`، +بازیابی روی سرورِ جدید در دیتابیسِ خالی‌شده، مقایسه‌ی تعدادِ ردیف‌ها. ۳) originِ هر دو دامنه در ArvanCloud به `78.38.35.216`. +۴) health و یک ورود و یک آزمون از بیرون. ۵) بکاپِ زنده از ۲۴۷ (اسلات `zareian_247`، تونل؛ `AllowTcpForwarding` روی این سرور +بسته است و برای کاربرِ بکاپ باید با `Match User` باز شود) و `pull-app-logs.sh` روی ۲۴۷ به آدرسِ جدید. ۶) CLAUDE.md و این سند. +تا سوئیچ، `deploy.sh` روی هر دو سرور اجرا شود تا کدِ دو طرف یکی بماند. + +### Qdrant + +**وضعِ فعلی Qdrant:** بردارهای RAG روی `https://qdrant.tadrisino2.ir` هستند (پشت ArvanCloud؛ سرورِ اصلی از بیرون پیدا +نیست و در فهرستِ سرورهای ما نیست. `rag_catalog` آن را سرورِ تیمِ دیگر می‌داند). نسخهٔ 1.17.0، ۳۴ collection، حدود +۱۰۸۸۰ نقطه، همه با بُعد ۱۵۳۶ و Cosine. + +**هدف:** همهٔ کتاب‌های ریاضی‌ای که در Qdrant هست (ریاضی، حسابان، هندسه، آمار و احتمال، گسسته؛ پایه‌های سوم تا دوازدهم) روی یک +Qdrant اختصاصی ببریم و اپ را به آن وصل کنیم، بدون ingest دوباره، چون ingest هزینهٔ GapGPT دارد. + +**کدام collectionها (۱۵ تا، حدود ۵۶۸۰ نقطه):** +- ریاضی سوم، چهارم، پنجم، ششم، هفتم، هشتم، نهم، دهم. +- حسابان یازدهم، دوازدهم. +- هندسه دهم، یازدهم، دوازدهم. +- آمار و احتمال یازدهم. +- گسسته دوازدهم. + +ریاضیِ سوم، ششم و هفتم را تیمِ دیگر ingest کرده، و صاحبِ محصول خواسته هر سه منتقل شوند. بقیهٔ collectionها (علوم، فارسی، +مطالعات اجتماعی، هدیهٔ آسمان، پیام‌های آسمان) در این برنامه نیستند. + +**اصولِ انتقال:** +- از هر collection یک snapshot بگیرید، فایلِ آن را منتقل و روی Qdrant جدید بارگذاری کنید (بدون فراخوانیِ OpenAI). +- بعد از انتقال: تعدادِ نقاط، بُعد و Cosine یکی باشند؛ یک بردارِ ذخیره‌شده را به‌عنوانِ query بدهید و همان نقطه بالا بیاید. +- `/api/rag/ingest` هنوز روی Qdrant فعلی می‌نویسد. در بازهٔ کپی ingest متوقف شود، یا بعد از سوئیچ نقاطِ تازه دوباره همگام شوند. +- `QDRANT_URL` و `QDRANT_API_KEY` را فقط **بعد** از تأییدِ کپی عوض کنید؛ زودتر عوض شود، تیوتور جوابِ ناقص می‌دهد. + +**باز:** محلِ سرورِ اصلیِ فعلیِ Qdrant (ادعای «روی سرورِ تیمِ دیگر» هنوز از روی سرور تأیید نشده). سرورِ جدید فعلاً به همان +`qdrant.tadrisino2.ir` وصل است. + ## لاگ‌ها هر درخواستِ `/api/` به‌صورتِ یک شیءِ JSON در هر خط لاگ می‌شود diff --git a/ops/applogs/archive-app-log.sh b/ops/applogs/archive-app-log.sh index 2037bd4..056bde1 100755 --- a/ops/applogs/archive-app-log.sh +++ b/ops/applogs/archive-app-log.sh @@ -1,11 +1,12 @@ #!/bin/bash -# روی ۲۴۹، هر شب (zareian-applog-archive.timer). app.log را به logs/archive/ می‌برد و فشرده می‌کند. +# روی سرورِ اپ، هر شب (zareian-applog-archive.timer). app.log را به logs/archive/ می‌برد و فشرده می‌کند. # برنامه با LOG_FILE_ROTATION=external از WatchedFileHandler استفاده می‌کند و پس از جابه‌جایی خودش app.log تازه # می‌سازد؛ خطی که در همان لحظه نوشته شود در فایلِ جابه‌جاشده می‌ماند، گم نمی‌شود. # این‌جا فقط ۳۰ روز می‌ماند (دیسکِ ۲۴۹ پر است) و فقط فایلی پاک می‌شود که ۲۴۷ گرفتنش را تأیید کرده # (`.shipped`)؛ نسخه‌ی همیشگی روی ۲۴۷ است (pull-app-logs.sh). فقط زیرِ ~/mathapp-v2/logs می‌نویسد. set -euo pipefail -LOGS=/home/administrator/mathapp-v2/logs +# پوشه‌ی پروژه از جای خودِ اسکریپت (ops/applogs/ → دو پوشه بالاتر)، تا روی هر سروری با هر کاربری درست باشد. +LOGS="$(cd "$(dirname "$0")/../.." && pwd)/logs" ARCH="$LOGS/archive" mkdir -p "$ARCH" chmod 750 "$ARCH"