make a deploy observable and one command instead of a checklist
بالا آوردنِ نسخهی جدید تا الان چند کارِ دستی به ترتیبِ درست بود (pull، نصبِ
وابستگیها، مهاجرت، استاتیک، ریاستارت) و فراموش شدنِ هر کدام اپ را میخواباند
با خطایی که از بیرون فقط «502 Bad Gateway» دیده میشد. همین الان هم سرور
دقیقاً به همین دلیل خوابیده: کامیتِ ac1b1af پکیجِ django-cors-headers را اضافه
کرد، و بدونِ pip install جنگو با ModuleNotFoundError بالا نمیآید.
deploy.sh همه را به ترتیب و idempotent انجام میدهد. pip install همیشه اجرا
میشود، نه فقط وقتی requirements عوض شده — تشخیصِ «عوض شده یا نه» خودش یک جای
فراموششدنیِ دیگر است. آخرِ کار خودش سلامت را بررسی میکند و اگر بالا نیامده
باشد علتهای رایج را چاپ میکند، بهجای اینکه کسی بعداً از بیرون کشفش کند.
GET /api/health وضعیت را بدونِ احراز و بدونِ SSH بیرون میدهد: دیتابیس،
مهاجرتهای اعمالنشده، کش، و شمارشِ پایه/درس/سوال روی همان سرور. مهمترینش
مهاجرتِ اعمالنشده است — حالتی که اپ ظاهراً بالا میآید و بعد زیرِ بارِ واقعی
با خطای ستونِ ناموجود میشکند. عمداً هیچ سکرتی برنمیگرداند، فقط بله/خیرِ
«تنظیم شده».
۵۰۳ برمیگرداند وقتی دیتابیس/کش/مهاجرت خراب است تا پایشِ خودکار بتواند رویش
حساب کند؛ نبودِ محتوا خرابی حساب نمیشود ولی گزارش میشود.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
51
README.md
51
README.md
@@ -110,6 +110,57 @@ python manage.py test # اجرای کل تستسوییت
|
||||
|
||||
## ۲. راهنمای دیپلوی پروداکشن
|
||||
|
||||
### بالا آوردنِ نسخهی جدید — یک دستور
|
||||
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
همین. اسکریپت به ترتیب کدِ تازه را میگیرد، وابستگیها را نصب میکند، مهاجرتها
|
||||
را اعمال میکند، فایلهای استاتیک را جمع میکند، سرویس را ریاستارت میکند، و در
|
||||
پایان **خودش بررسی میکند که واقعاً بالا آمده یا نه**. اگر بالا نیامد، علتهای
|
||||
رایج را چاپ میکند.
|
||||
|
||||
چرا این مهم است: قبلاً اینها چند کارِ دستی به ترتیبِ درست بودند و فراموش شدنِ
|
||||
هر کدام اپ را میخواباند، با خطایی که گویا نبود. مثلاً اضافه شدنِ یک پکیجِ جدید
|
||||
به `requirements.txt` بدونِ `pip install` باعثِ `ModuleNotFoundError` موقعِ بالا
|
||||
آمدن میشود و کاربر فقط `502 Bad Gateway` میبیند. اسکریپت همیشه `pip install`
|
||||
را اجرا میکند تا این حالت اصلاً پیش نیاید.
|
||||
|
||||
بارِ اول، نامِ سرویس را بدهید تا دفعههای بعد خودکار ریاستارت شود:
|
||||
|
||||
```bash
|
||||
TADRISINO_SERVICE=<نامِ سرویس> ./deploy.sh
|
||||
```
|
||||
|
||||
متغیرهای اختیاری: `SKIP_PULL=1` (بدونِ git pull)، `TADRISINO_HEALTH_URL`،
|
||||
`PIP_INDEX_URL` (اگر pypi.org تایماوت میدهد).
|
||||
|
||||
### بررسیِ سلامت از بیرون
|
||||
|
||||
```bash
|
||||
curl https://<host>/api/health
|
||||
```
|
||||
|
||||
بدونِ احرازِ هویت و بدونِ SSH میگوید دیتابیس سالم است یا نه، مهاجرتِ
|
||||
اعمالنشده مانده یا نه، کش کار میکند یا نه، و چند پایه/درس/سوال روی آن سرور
|
||||
هست. `200` یعنی سالم، `503` یعنی چیزی واقعاً خراب است. هیچ سکرتی برنمیگرداند.
|
||||
|
||||
این همان چیزیست که جلوی «کد رفته ولی مهاجرت اجرا نشده» را میگیرد — حالتی که
|
||||
اپ ظاهراً بالا میآید و بعد زیرِ بارِ واقعی میشکند.
|
||||
|
||||
### مدیریتِ محتوا بدونِ ترمینال
|
||||
|
||||
سوالها از پنلِ ادمین وارد و خارج میشوند، نه با دستور روی سرور:
|
||||
|
||||
- `/admin/content/question/` → دکمهی **«وارد کردنِ سوالها از فایل»**
|
||||
- برای گرفتنِ نمونه: چند سوال را انتخاب کنید → اکشنِ **«دریافتِ فایلِ سوالهای
|
||||
انتخابشده»**. خروجی دقیقاً همان قالبیست که ورودی میپذیرد.
|
||||
|
||||
فایلِ نامعتبر **هیچ چیزی نمینویسد** — یا همهی سوالها وارد میشوند یا هیچکدام،
|
||||
و خطا میگوید کدام ردیف ایراد دارد.
|
||||
|
||||
|
||||
### متغیرهای محیطی موردنیاز
|
||||
| متغیر | لازم در پروداکشن | توضیح |
|
||||
|---|---|---|
|
||||
|
||||
Reference in New Issue
Block a user