When your budget is literally nothing, you get creative. That's what the team behind G3HUB discovered when building a production Learning Management System with React 18 + Vite on the frontend, Node.js 20 + Express on the backend, and PostgreSQL 15 via Supabase for persistence. The catch? Their only infrastructure was a cPanel shared hosting account from Truehost Nigeria already running WordPress—no VPS, no cloud VM, just creative problem-solving and several walls that seemed impossible to climb. The final architecture splits three layers across three free services: the React frontend lives in public_html/learn/ on Truehost's LiteSpeed server, the Node.js API runs as a 6.4MB esbuild bundle on Render's free tier, and the PostgreSQL database connects via Supabase's Session Pooler. The key insight that made it all work: PHP's cURL functions bypass Apache mod_proxy restrictions entirely, allowing shared hosting to forward API requests to external HTTPS endpoints without CORS headaches. The first wall hit immediately. When attempting to run the Node.js API directly on Truehost's Node.js App feature and connect to Supabase, every database connection crashed with ECONNREFUSED. Testing confirmed the problem: outbound port 5432 (PostgreSQL) was blocked at the network level. Truehost support's response was blunt: 'If your application requires direct connectivity to an external PostgreSQL database, we recommend migrating to a VPS or dedicated server environment.' Shared hosting blocks PostgreSQL. Full stop. The fix was moving the API to Render, which has no such outbound restrictions. The second wall came from pnpm workspace dependencies. When pushing the api-server folder to GitHub for Render deployment, the build failed immediately with 'workspace:* — Not found' errors. The package.json contained @workspace/db and @workspace/api-zod references that only exist within the monorepo. Since esbuild had already bundled everything into a self-contained dist/index.mjs, the solution was replacing the full package.json with just pdfkit as an external dependency—everything else was already compiled in. Wall three was Apache mod_proxy refusing to forward requests to Render's external HTTPS URL. Requests timed out consistently, even though curl from the same server could reach g3hub-learnflow-api.onrender.com/api/healthz perfectly fine. The module configuration itself seemed restricted on shared hosting. Enter the PHP cURL proxy: a single proxy.php script that forwards all /api/* requests to Render while maintaining cookies, headers, and request methods. Because frontend and proxy live on the same domain (learn.g3hub.com.ng), there are no CORS issues—the browser thinks it's talking to one server. Two more Supabase gotchas nearly derailed everything. First: 'self-signed certificate in certificate chain' errors from Node.js not trusting the connection pooler's SSL chain. The workaround is setting NODE_TLS_REJECT_UNAUTHORIZED=0 (the connection stays encrypted, just unverified). Second: the Session Pooler requires a special username format—postgres.
Key Takeaways
- Shared hosting blocks outbound PostgreSQL (port 5432/6543); use external API hosts instead
- esbuild bundles make monorepo deployment trivial—dist/index.mjs needs only pdfkit as an external dependency
- Apache mod_proxy restrictions on shared hosting can be bypassed with PHP cURL proxies
- Supabase Session Pooler requires postgres.
username format and SSL workarounds - Test outbound connectivity from your server before building any deployment pipeline
The Bottom Line
This is the kind of article that makes you appreciate both the ingenuity and the absurdity of making $0/month infrastructure work for production. The PHP proxy hack is genuinely clever—but it's also a red flag that you're fighting your tools instead of using the right ones. If you're building anything beyond a static site, budget for that $5 VPS. Your future self will thank you.