دیتابیس SQLite و دیپلوی Forge: دام پنهانی که همه چیز رو پاک میکنه
خلاصهٔ کاملتر
اگه یه اپ لاراولی داری که روی Laravel Forge هاست شده و از SQLite بهعنوان دیتابیس استفاده میکنی، ممکنه با یه باگ خاموش و خطرناک دستوپنجه نرم کنی: هر بار که دیپلوی میکنی، تمام دادههات ناپدید میشن. نه خطایی، نه هشداری، فقط یه دیتابیس خالی تازه.
ماجرا از اینجاست که Forge برای zero-downtime deployment هر ریلیز جدید رو توی یه پوشه مجزا زیر releases/ میریزه و بعد یه symlink به اسم current رو به اون پوشه اشاره میده. یعنی هر ریلیز کاملاً مستقل و بهنوعی «یکبار مصرف» در نظر گرفته میشه. مشکل اینجاست که فایل database/database.sqlite لاراول هم داخل همین پوشه ریلیز قرار داره و وقتی symlink عوض میشه، اون فایل دیگه در دسترس نیست. ریکوئست بعدی یه فایل SQLite خالی جدید میسازه و انگار نه انگار.
Forge یه مفهوم به اسم shared paths داره؛ یعنی فایلها یا پوشههایی که یهبار در root سایت وجود دارن (مثلاً /home/forge/example.com/) و توی هر ریلیز جدید بهشون symlink زده میشه. بهصورت پیشفرض، هم فایل .env و هم پوشه storage/ بهعنوان shared path تنظیم شدن. به همین دلیله که متغیرهای محیطی و فایلهای آپلودشده بین دیپلویها زنده میمونن.
راهحل اینه که فایل SQLite رو داخل storage/ بذاری، مثلاً در مسیر storage/database/database.sqlite. چون این پوشه از قبل shared هست، دیتابیست بدون هیچ تنظیم اضافهای بین تمام ریلیزها پایدار میمونه. میتونی از Settings → Deployments → Shared Paths هم چک کنی یا تغییرات بدی، ولی معمولاً نیازی نیست.
شاید بپرسی چرا کل پوشه database/ رو shared نکنیم؟ چون اون پوشه شامل migrations/، seeders/ و factories/ هم میشه که کدهای پروژهان و باید با هر ریلیز تازه بیان. اگه کل پوشه رو share کنی، migration های جدید هیچوقت روی سرور نمیرسن. پس بهترین کار اینه که فقط دیتابیس رو بذاری داخل storage/ و بقیه چیزها رو دست نزنی.
بعد از انتقال فایل، باید مسیر پیشفرض SQLite رو در config/database.php هم آپدیت کنی تا از storage_path() استفاده کنه:
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DB_URL'),
'database' => env('DB_DATABASE', storage_path('database/database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],اگه مقدار DB_DATABASE رو در .env تنظیم میکنی، حتماً مسیر مطلق فایل رو بنویس، مثلاً /home/forge/example.com/storage/database/database.sqlite تا هیچ ابهامی نباشه.
اگه روی سرور دادهای داری که نمیخوای از دست بدی، قبل از دیپلوی بعدی باید فایل رو به مسیر جدید کپی کنی. بعد از اینکه تغییرات config رو به Git پوش کردی و یه دیپلوی زدی، لاراول از همون فایل shared استفاده میکنه و از این به بعد هیچ دیپلویی دیگه دیتابیست رو پاک نمیکنه.
نکات کلیدی:
- Forge در zero-downtime deployment هر ریلیز رو داخل پوشه مجزا میریزه و database.sqlite پیشفرض لاراول با هر دیپلوی از بین میره
- پوشه storage/ از قبل بهعنوان shared path در Forge تنظیم شده و بین تمام ریلیزها پایدار میمونه
- دیتابیس SQLite رو باید به storage/database/database.sqlite منتقل کنی
- در config/database.php از storage_path() بهجای database_path() استفاده کن
- کل پوشه database/ رو shared نکن چون migration ها و کدهای دیگه رو هم فریز میکنه
- اگه داده داری، قبل از دیپلوی بعدی فایل SQLite رو به مسیر جدید کپی کن




