استقرار اپلیکیشن‌های فول‌استک روی زیرساخت‌های رایگان

ما یک سیستم مدیریت یادگیری (LMS) برای G3HUB ساختیم. تکنولوژی‌های مورد استفاده: React 18، Node.js 20 و PostgreSQL 15.

ما VPS نداشتیم. بودجه‌ای برای سرویس‌های ابری نداشتیم. تنها چیزی که داشتیم یک اکانت هاست اشتراکی cPanel و یک ضرب‌الاجل (deadline) بود.

بیشتر آموزش‌ها فرض می‌کنند که شما یک سرور اختصاصی دارید. ما مجبور شدیم راهی پیدا کنیم تا سرویس‌های مختلف را با هزینه ۰ دلار در ماه، با هم در ارتباط قرار دهیم.

معماری

• فرانت‌اند: React + Vite (میزبانی شده روی cPanel) • بک‌اند: Node.js + Express (میزبانی شده روی طرح رایگان Render) • پایگاه داده: PostgreSQL (میزبانی شده روی طرح رایگان Supabase)

چالش‌ها و راه‌حل‌ها

۱. هاست اشتراکی مانع اتصال به پایگاه داده می‌شود ما سعی کردیم API مربوط به Node.js را روی cPanel اجرا کنیم. اما شکست خورد، زیرا هاست اجازه اتصالات خروجی به PostgreSQL روی پورت 5432 را نمی‌داد. راه‌حل: انتقال API به Render. سرویس Render اجازه این اتصالات را می‌دهد.

۲. خطاهای استقرار در Monorepo سرویس Render نمی‌توانست وابستگی‌های workspace در pnpm مانند @workspace/db را تشخیص دهد. راه‌حل: ما از esbuild استفاده کردیم تا همه چیز را در یک فایل واحد ۶.۴ مگابایتی باندل (bundle) کنیم. سپس از یک package.json حداقلی که فقط شامل وابستگی‌های خارجی بود استفاده کردیم. این کار باعث شد API مستقل و خودکفا شود.

۳. مشکل CORS و پروکسی ماژول mod_proxy در آپاچی (Apache) روی هاست اشتراکی محدود بود. ما نمی‌توانستیم به راحتی درخواست‌های API را از فرانت‌اند به Render هدایت کنیم. راه‌حل: استفاده از یک پروکسی PHP cURL. فرانت‌اند اسکریپت PHP محلی را فراخوانی می‌کند و اسکریپت PHP درخواست را به Render ارسال می‌کند. این کار مشکلات CORS و محدودیت‌های فایروال را دور می‌زند.

۴. خطاهای گواهینامه SSL سیستم مدیریت اتصال (connection pooler) در Supabase باعث بروز خطاهای SSL در Node.js می‌شد. راه‌حل: متغیر محیطی NODE_TLS_REJECT_UNAUTHORIZED=0 را تنظیم کردیم.

جزئیات هزینه‌ها

• cPanel: ۰ دلار (موجود) • Render: ۰ دلار (طرح رایگان) • Supabase: ۰ دلار (طرح رایگان) • مجموع: ۰ دلار در ماه

نکات کلیدی برای مهندسان

  • اتصال خروجی را زودتر تست کنید. قبل از نوشتن کد، بررسی کنید که آیا سرور شما واقعاً می‌تواند با پایگاه داده ارتباط برقرار کند یا خیر.
  • برای Monorepoها از esbuild استفاده کنید. استقرار یک فایل باندل‌شده واحد بسیار آسان‌تر از یک ساختار پوشه‌بندی پیچیده است.
  • از UptimeRobot استفاده کنید. طرح رایگان Render پس از ۱۵ دقیقه به حالت خواب (sleep) می‌رود. یک پینگ ساده آن را بیدار نگه می‌دارد.
  • از کاراکترهای خاص در رمز عبور پایگاه داده خودداری کنید. استفاده از @ یا ! در رشته اتصال (connection string) باعث دردسرهای بی‌پایان در URL-encoding می‌شود.

اگر بودجه دارید، یک VPS ۵ دلاری بخرید. این کار تمام این موانع را از بین می‌برد. اما اگر بودجه‌ای ندارید، مسیریابی خلاقانه (creative routing) امکان ساخت اپلیکیشن‌های عملیاتی (production) را فراهم می‌کند.

Source: https://dev.to/oyohedmond/deploying-a-full-stack-lms-on-shared-hosting-render-free-the-hard-way-4ke0

Optional learning community: https://t.me/GyaanSetuAi