seed script
This commit is contained in:
1 parent
fa9d154db9
commit
08c30aa47f
15 files changed
+496
-17
No files matched your search
+11
-13
@@ -10,14 +10,15 @@ PostgreSQL جزو این Compose نیست و از دیتابیس مدیریت
|
||||
|
||||
## 1. Volumeهای Coolify
|
||||
|
||||
پیش از اولین deploy دو Docker volume با همین نامها ایجاد کنید:
|
||||
پیش از اولین deploy سه Docker volume با همین نامها ایجاد کنید:
|
||||
|
||||
```text
|
||||
customer_ticket_static
|
||||
customer_ticket_media
|
||||
customer_ticket_seed
|
||||
```
|
||||
|
||||
در صورت انتخاب نام دیگر، متغیرهای `STATIC_VOLUME_NAME` و `MEDIA_VOLUME_NAME` را مطابق آن تنظیم کنید. media حاوی آپلودهای ماندگار است. static در هر startup دوباره با `collectstatic` تکمیل میشود اما برای اشتراک بین web و Nginx volume لازم دارد.
|
||||
در صورت انتخاب نام دیگر، متغیرهای `STATIC_VOLUME_NAME`، `MEDIA_VOLUME_NAME` و `SEED_VOLUME_NAME` را مطابق آن تنظیم کنید. media حاوی آپلودهای ماندگار است. static در هر startup دوباره با `collectstatic` تکمیل میشود اما برای اشتراک بین web و Nginx volume لازم دارد. سه فایل تولیدشده در `production-seed/` باید پیش از اولین startup داخل ریشه volume سوم قرار گیرند.
|
||||
|
||||
## 2. دامنهها و Traefik خود Coolify
|
||||
|
||||
@@ -47,7 +48,9 @@ DATABASE_WAIT_TIMEOUT=60
|
||||
|
||||
STATIC_VOLUME_NAME=customer_ticket_static
|
||||
MEDIA_VOLUME_NAME=customer_ticket_media
|
||||
SEED_VOLUME_NAME=customer_ticket_seed
|
||||
MEDIA_SIGNING_SECRET=<separate-random-secret-at-least-32-characters>
|
||||
REQUIRE_PRODUCTION_SEED=1
|
||||
```
|
||||
|
||||
نام دیتابیس انتهای URL باید نام واقعی دیتابیس باشد. اگر دیتابیس ساختهشده `customerTicket` است، URL باید به `/customerTicket` ختم شود؛ URLی که به `/postgres` ختم میشود به دیتابیس پیشفرض `postgres` متصل خواهد شد. اگر password شامل `@`، `:`، `/`، `#` یا `%` است آن را URL-encode کنید.
|
||||
@@ -115,17 +118,12 @@ SECURE_HSTS_PRELOAD=false
|
||||
## 7. ترتیب اولین deploy
|
||||
|
||||
1. volumeها و database خالی را ایجاد کنید.
|
||||
2. Environment Variables را در Coolify وارد کنید.
|
||||
3. Compose را deploy، دامنه اصلی را به `web:8000` و pathهای static/media گفتهشده را به `nginx:80` متصل کنید.
|
||||
4. log سرویس `web` را برای موفقیت migrate، bootstrap، collectstatic و Gunicorn بررسی کنید.
|
||||
5. log سرویس `notification-worker` را بررسی کنید؛ container باید Running بماند.
|
||||
6. یکبار superuser بسازید:
|
||||
|
||||
```bash
|
||||
docker compose exec web python manage.py createsuperuser
|
||||
```
|
||||
|
||||
7. در پنل مدیریت، SMS templateها و `NotificationPolicy`ها را بررسی کنید و با گیرنده آزمایشی مجاز یک SMS و یک پیام Bale واقعی بفرستید.
|
||||
2. طبق `docs/PRODUCTION_SEED.md` سه فایل seed را داخل volume `customer_ticket_seed` قرار دهید.
|
||||
3. Environment Variables را در Coolify وارد کنید.
|
||||
4. Compose را deploy، دامنه اصلی را به `web:8000` و pathهای static/media گفتهشده را به `nginx:80` متصل کنید.
|
||||
5. log سرویس `web` را برای موفقیت migrate، import production seed، collectstatic و Gunicorn بررسی کنید. وقتی seed موجود است، bootstrap عمداً اجرا نمیشود تا snapshot تغییر نکند.
|
||||
6. log سرویس `notification-worker` را بررسی کنید؛ container باید Running بماند.
|
||||
7. با superuser منتقلشده از SQLite وارد شوید و با گیرنده آزمایشی مجاز یک SMS و یک پیام Bale واقعی بفرستید.
|
||||
|
||||
## 8. کنترل سلامت و عیبیابی
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# انتقال خودکار SQLite به PostgreSQL Production
|
||||
|
||||
این فرایند تمام دادههای پایدار فعلی را منتقل میکند:
|
||||
|
||||
- کاربران، hash رمزهای قابل استفاده، superuser، گروهها و permissionها
|
||||
- واحدهای سازمانی، عضویتها، نقشها و پروفایل پرسنل
|
||||
- مشتریان، گروه مخاطبان، دستهبندیها و SLA
|
||||
- branding، عنوان صفحات، SMS templateها، NotificationPolicy و سیاست فایلها
|
||||
- تیکتها، ارسالهای گروهی، رویدادها، پیامها، رسیدهای خواندن و attachmentها
|
||||
- تمام فایلهای موجود در `MEDIA_ROOT`، شامل branding، avatar و فایل تیکت
|
||||
|
||||
دادههای موقتی و خطرناک زیر عمداً منتقل نمیشوند: sessionها، OTPهای قبلی، Magic Linkهای قبلی، admin log و `NotificationJob`. انتقال outbox قبلی میتوانست بعد از بالا آمدن worker باعث ارسال مجدد SMS یا Bale شود.
|
||||
|
||||
## خروجی ساختهشده
|
||||
|
||||
دستور زیر از SQLite فعلی snapshot میگیرد:
|
||||
|
||||
```powershell
|
||||
.\.venv\Scripts\python.exe manage.py export_production_seed --output production-seed --force
|
||||
```
|
||||
|
||||
برای وضعیت فعلی پروژه خروجی قبلاً تولید شده و شامل ۳۹۵ رکورد پایدار و ۵۷ فایل media است:
|
||||
|
||||
```text
|
||||
production-seed/
|
||||
data.json.gz
|
||||
media.tar.gz
|
||||
manifest.json
|
||||
```
|
||||
|
||||
این پوشه شامل اطلاعات شخصی و password hash است و عمداً توسط Git و Docker ignore میشود. آن را commit، ایمیل یا در فضای عمومی بارگذاری نکنید.
|
||||
|
||||
## انتقال امن به volume سرور
|
||||
|
||||
در Coolify volume خارجی `customer_ticket_seed` را ایجاد کنید. سه فایل بالا باید مستقیماً در ریشه آن قرار بگیرند، به شکلی که container مسیر زیر را ببیند:
|
||||
|
||||
```text
|
||||
/app/production-seed/manifest.json
|
||||
/app/production-seed/data.json.gz
|
||||
/app/production-seed/media.tar.gz
|
||||
```
|
||||
|
||||
فایلها را با قابلیت Persistent Storage/File Mount خود Coolify یا یک انتقال امن مانند SCP به سرور ببرید. اگر روی سرور در `/tmp/customer-ticket-seed` قرار گرفتهاند، مدیر سرور میتواند volume را اینگونه پر کند:
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-v customer_ticket_seed:/target \
|
||||
-v /tmp/customer-ticket-seed:/source:ro \
|
||||
alpine:3.20 sh -c 'cp /source/data.json.gz /source/media.tar.gz /source/manifest.json /target/'
|
||||
```
|
||||
|
||||
پس از کپی، نسخه موجود در `/tmp` را امن حذف کنید. volume seed در Compose فقط read-only داخل web mount میشود.
|
||||
|
||||
## اجرای خودکار
|
||||
|
||||
در اولین startup سرویس web ترتیب زیر اجرا میشود:
|
||||
|
||||
1. انتظار برای PostgreSQL
|
||||
2. اجرای migrationها
|
||||
3. اعتبارسنجی SHA-256 فایلهای seed
|
||||
4. اطمینان از خالی بودن PostgreSQL و media volume
|
||||
5. حذف defaultهای data migration و import کامل snapshot
|
||||
6. انتقال media به volume اصلی
|
||||
7. ثبت `ProductionSeedState`
|
||||
8. رد کردن `bootstrap` برای حفظ دقیق snapshot بهعنوان منبع authoritative
|
||||
9. اجرای `collectstatic` و Gunicorn
|
||||
|
||||
در deployهای بعدی checksum قبلاً ثبتشده تشخیص داده میشود و import دوباره انجام نمیشود. اگر bundle نباشد، با `REQUIRE_PRODUCTION_SEED=1` سرویس عمداً متوقف میشود تا production ناقص بالا نیاید.
|
||||
|
||||
## محدودیتهای ایمنی
|
||||
|
||||
- import فقط روی PostgreSQL اجرا میشود.
|
||||
- دیتابیس دارای User یا seed قبلی با checksum متفاوت پذیرفته نمیشود.
|
||||
- media volume غیرخالی overwrite نمیشود.
|
||||
- مسیرهای مشکوک، symlink و path traversal در archive رد میشوند.
|
||||
- checksum هر دو فایل پیش از هر تغییر بررسی میشود.
|
||||
- شکست import باعث rollback دیتابیس و حذف فایلهای کپیشده همان اجرا میشود.
|
||||
|
||||
اگر واقعاً میخواهید production بدون snapshot بالا بیاید، `REQUIRE_PRODUCTION_SEED=0` بگذارید؛ در این حالت فقط bootstrap استاندارد اجرا میشود و کاربران دارای password فعلی SQLite منتقل نخواهند شد.
|
||||
Reference in new issue
Block a user