Laravel & MERN Stack Deployment on VPS — Done Right, the First Time

Published:
Last updated:

Most developers can write an app. Getting it to run correctly on a production server — with zero errors, proper SSL, running queues, and a hardened firewall — is a different job. That's where I come in.

I'm Muhammad Zeeshan, a full stack developer based in Pakistan. I've spent the last few years working on Laravel backends at a government IT organization, building MERN stack apps freelance, and deploying them to real production servers on DigitalOcean, AWS, and Hostinger. I know what breaks, I know why, and I know how to fix it before it ever reaches your users.

This isn't a managed service or an automated platform. You get a real developer who logs into your server, configures everything by hand to fit your specific app, and documents every single change.


Laravel and Mern stack web apps deployment service


What I Actually Do

Laravel Deployment on VPS

When you hire me to deploy a Laravel app, here's the short version: I set up the full LEMP stack from scratch, write a custom Nginx server block for your domain, configure PHP-FPM for your PHP version, secure the .env file, run composer install with production flags, handle storage permissions, install Let's Encrypt SSL, and set up Supervisor to keep your queue workers alive — even after a reboot.

The parts most people miss:

  • OPcache — I enable and tune it. Your cold boot response time drops from 700ms+ to under 250ms.
  • Laravel config and route cachingphp artisan config:cache, route:cache, view:cache. Three commands that make a real difference.
  • Supervisor for queues — Without it, queue workers die silently. Nobody notices until a user's email never arrives.
  • Fail2ban — Blocks brute-force SSH attempts automatically. Most VPS guides skip this.
  • Security headers in Nginx — X-Frame-Options, X-Content-Type-Options, Referrer-Policy. Google and browsers care.

If your app uses Laravel Scheduler, I wire it to cron properly. If you're on shared hosting, I handle the document root redirect and PHP version compatibility issues that almost always trip people up.

MERN Stack Deployment on VPS

MERN deployments have a different set of failure points. The most common one I see: Node.js running directly without PM2, which means your backend goes down the moment you close the SSH session.

I configure PM2 to manage your Express.js process — it auto-restarts on crash, survives server reboots, and gives you proper logging. Then I set up Nginx as a reverse proxy in front of it, so traffic hits Nginx on port 80/443 and gets forwarded internally to Node.

For the React frontend, I build it with npm run build and either serve the static files from Nginx directly, or integrate it into the same domain if you're running a monorepo setup.

On MongoDB: if you're using Atlas, I configure the connection string and IP whitelisting. If you want a local instance, I install it, lock down the bind address, and set up authentication.

Platforms I Deploy On

DigitalOcean Droplets

My most common deployment environment. I provision fresh Ubuntu 22.04 Droplets, set up a non-root sudo user, disable root SSH login, configure UFW, and build out the LEMP stack. DigitalOcean Managed Databases and Spaces work well with Laravel — I've set up both.

AWS EC2 & Lightsail

For projects that need AWS — EC2 with proper security groups, Elastic IPs, S3 for file storage, and RDS for MySQL. Lightsail works well for smaller apps where you want AWS infrastructure without the full EC2 complexity.

Hostinger VPS

A solid affordable option for solo projects and early-stage startups. I've deployed multiple Laravel apps on Hostinger's Ubuntu VPS plans. The setup process is the same as DigitalOcean, minus a few DigitalOcean-specific features.

cPanel / Shared Hosting

Tricky, but workable. The main issues are always the same: wrong document root, wrong PHP version, Composer not on PATH, and symlink issues with the public/ folder. I've worked through all of them. If your host supports SSH access, I can almost always get Laravel running.

CI/CD Pipeline Setup

If your team deploys frequently, manual SSH is a bottleneck you don't need. I set up GitHub Actions workflows that trigger on push to main — pulling the latest code, running migrations, clearing caches, and restarting queue workers automatically.

This is optional and adds time to the project, but for teams shipping more than once a week, it pays for itself immediately.

Problems I Fix Fast

Most of the time, people reach out because something is already broken. These are the exact errors I've fixed the most often:

"Laravel gives 500 errors on the server but works locally"
Almost always permissions on storage/ or bootstrap/cache/, a missing or wrong .env, or APP_KEY not set. Sometimes it's a PHP extension missing on the server that exists locally.

"My Node.js app goes down randomly"
PM2 not configured, or configured but not set to persist across reboots. pm2 startup + pm2 save is the fix. Takes 30 seconds once you know what you're looking for.

"SSL is installed but the site shows as not secure"
Usually mixed content — the app is behind a load balancer or proxy and doesn't know to trust HTTPS. The fix is FORCE_HTTPS=true in .env or configuring TrustedProxies middleware correctly.

"Database connection works locally, fails on server"
MySQL bind-address is set to 127.0.0.1, blocking external connections. Or the DB host in .env is still localhost when it should be 127.0.0.1 (different under certain PHP configurations).

"CI/CD pipeline fails on deploy"
SSH key not added to the server's authorized_keys, wrong file path in the workflow, or a step that requires interactive input and hangs. I've debugged these at 2am. I know what to look for.

What the Numbers Look Like

On a typical Laravel deployment on a 1GB DigitalOcean Droplet, here's what enabling OPcache, route caching, and config caching actually does to response time — before and after, measured with Apache Bench:

  • Without optimization: 620–900ms average response time
  • With OPcache + Laravel caching: 180–260ms average response time

That's not a code change. That's pure configuration. It takes about 10 minutes to set up and the difference is immediate.

What You Get

Every deployment includes:

  • Full server setup from a fresh Ubuntu install (or from your existing server)
  • Custom Nginx or Apache configuration for your specific app and domain
  • Let's Encrypt SSL with auto-renewal
  • PHP-FPM tuning, OPcache enabled
  • .env configured with your production credentials
  • Supervisor setup for queue workers (if your app uses queues)
  • UFW firewall configured with minimal open ports
  • Fail2ban for SSH brute-force protection
  • A written summary of every configuration change made

Optional add-ons:

  • GitHub Actions CI/CD pipeline
  • Redis setup for caching and session storage
  • Multiple apps on a single VPS with separate Nginx server blocks
  • MongoDB Atlas or local MongoDB installation
  • Server migration from one provider to another

Engagement Options

I work through Upwork for all paid engagements, which gives you payment protection and a verifiable track record.

One-time deployment — Fixed scope, fixed price. Get your app live on a properly configured VPS. Most standard deployments are done within 4–8 hours.

Emergency fix — Production is down and you need it back up fast. I prioritize these and respond within a few hours during Pakistan working hours (PKT, UTC+5).

Ongoing support retainer — Monthly arrangement for teams that need someone on call for server-side changes, security patches, and uptime monitoring.

A Note on What I Don't Do

I don't touch application code as part of a deployment engagement. If your app has bugs that need fixing before it can go live, that's a separate scope of work. What I do is take your working app and make it run correctly, securely, and fast on a production server.

I also don't use Forge, Ploi, or other deployment tools that abstract away the server. I configure everything directly. You end up with a server you understand and can maintain, not a black box.

Ready to Deploy?

If your app is built and you need it live — or if your current server is a mess you've been afraid to touch — reach out. Tell me what you're running (Laravel, MERN, or both), where you want to host it, and what's blocking you right now. I'll tell you what the work involves and how long it'll take.