استقرار یک LMS فول‌استک روی هاست اشتراکی و Render

ما یک اپلیکیشن عملیاتی (production) با Node.js، React و PostgreSQL را بدون استفاده از VPS عرضه کردیم.

ما یک سیستم مدیریت یادگیری (LMS) کامل برای G3HUB ساختیم. این پشته تکنولوژی (stack) شامل موارد زیر بود: • فرانت‌اند: React 18، Vite و TailwindCSS • بک‌اند: Node.js 20 و Express 5 • پایگاه داده: PostgreSQL 15 از طریق Supabase • ORM: Drizzle ORM

ما هیچ ماشین مجازی ابری (cloud VM) یا VPS نداشتیم. ما فقط یک حساب هاست اشتراکی cPanel داشتیم که از قبل یک سایت وردپرس را اجرا می‌کرد. در اینجا نحوه انجام این کار را توضیح می‌دهیم.

تفکیک زیرساخت ما نمی‌توانستیم Node.js و PostgreSQL را روی یک سرور اجرا کنیم. بنابراین اپلیکیشن را بین سه سرویس تقسیم کردیم: • فرانت‌اند: هاست اشتراکی cPanel (فایل‌های استاتیک) • API: سرویس Render (پلن رایگان) • پایگاه داده: Supabase (پلن رایگان)

بزرگ‌ترین موانع

۱. بن‌بست پایگاه داده ما سعی کردیم API مربوط به Node.js را مستقیماً روی cPanel اجرا کنیم، اما بلافاصله با شکست مواجه شد. ارائه‌دهندگان هاست اشتراکی اغلب اتصالات خروجی (outbound connections) را روی پورت ۵۴۳۲ مسدود می‌کنند. این یعنی اپلیکیشن شما نمی‌تواند با یک پایگاه داده خارجی ارتباط برقرار کند. برای حل این مشکل، API را به Render منتقل کردیم.

۲. دردسر Monorepo کد ما از pnpm workspaces استفاده می‌کرد. وقتی آن را به Render ارسال (push) کردیم، فرآیند ساخت (build) با شکست مواجه شد، زیرا Render وابستگی‌های (dependencies) فضای کاری محلی ما را شناسایی نمی‌کرد. راه حل: ما از esbuild استفاده کردیم تا همه چیز را در یک فایل واحد ۶.۴ مگابایتی باندل (bundle) کنیم. سپس فایل package.json پیچیده را با یک نسخه حداقلی که فقط شامل وابستگی‌های خارجی بود، جایگزین کردیم.

۳. جنگ CORS و پروکسی ما سعی کردیم از Apache mod_proxy برای هدایت فراخوانی‌های API از دامنه خودمان به Render استفاده کنیم، اما با خطای زمان انتظار (timeout) مواجه شدیم. هاست‌های اشتراکی اغلب این ماژول را محدود می‌کنند. راه حل: ما از یک پروکسی PHP cURL استفاده کردیم. از آنجایی که فرانت‌اند و اسکریپت PHP روی یک دامنه قرار داشتند، از تمام مشکلات CORS جلوگیری کردیم. اسکریپت PHP درخواست‌ها را به‌صورت بی‌صدا به Render ارسال می‌کند.

نکاتی برای استقرار (Deployment) • عملیات build را در PowerShell انجام دهید، نه Git Bash. ویندوز متغیرهای محیطی (environment variables) را در Git Bash متفاوت مدیریت می‌کند. • از رمز عبور پایگاه داده بدون کاراکترهای خاص استفاده کنید. کاراکترهایی مانند @ یا ! نیاز به URL encoding دارند و باعث خطای اتصال می‌شوند. • از UptimeRobot استفاده کنید. پلن رایگان Render پس از ۱۵ دقیقه به حالت خواب (sleep) می‌رود. یک ping به نقطه پایانی (endpoint) بررسی سلامت (health check) خود تنظیم کنید تا سرویس را فعال نگه دارید.

هزینه کل زیرساخت: ۰ دلار در ماه.

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

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