Deploy Laravel + Next JS in VPS
A complete guide to deploying a Laravel API and Next.js frontend on a VPS with Nginx, PM2, PHP 8.3, MySQL, and SSL.
Khaled Saifullah
For a production setup, I recommend:
Domain
│
├── example.com → Next.js Frontend
│
└── api.example.com → Laravel Backend APIServer stack:
Ubuntu 24.04
Nginx
PHP 8.3
MySQL
Node.js
PM2
Certbot SSLStep 1: Login to VPS
From Hostinger panel: VPS → Manage → SSH Access You will get: IP Address: xxx.xxx.xxx.xxx Username: root Password:
Connect using SSH:
ssh root@YOUR_SERVER_IPExample:
ssh root@123.45.67.89Step 2: Update Ubuntu
apt update
apt upgrade -yInstall basic tools:
apt install curl wget git unzip nano -yStep 3: Point Domain to VPS
Go to your domain DNS management. Create these records:
Main Website (Next.js)
Type: A
Name: @
Value: YOUR_VPS_IP
TTL: 3600
Example:
example.com → 123.45.67.89
API Subdomain (Laravel)
Create:
Type: A
Name: api
Value: YOUR_VPS_IP
TTL: 3600
Result:
api.example.com → 123.45.67.89Wait 5-30 minutes. Check:
ping example.com
ping api.example.comStep 4: Install Nginx
apt install nginx -yCheck:
systemctl status nginxOpen firewall:
ufw allow 'Nginx Full'
ufw enableStep 5: Install PHP for Laravel
Install PHP 8.3:
apt install software-properties-common -y
add-apt-repository ppa:ondrej/php
apt updateInstall:
apt install php8.3 php8.3-fpm php8.3-mysql php8.3-cli php8.3-curl php8.3-mbstring php8.3-xml php8.3-zip php8.3-gd -yCheck:
php -vStep 6: Install MySQL
apt install mysql-server -ySecure:
mysql_secure_installationLogin:
mysqlCreate database:
CREATE DATABASE laravel_db;
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'StrongPassword';
GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;Step 7: Deploy Laravel Backend
Create folder:
mkdir -p /var/www/apiGo there:
cd /var/www/apiClone your project:
git clone YOUR_GITHUB_REPO .Example:
git clone https://github.com/user/project.git .Install Composer:
apt install composer -yInstall packages:
composer install --no-dev --optimize-autoloaderCopy environment:
cp .env.example .envEdit:
nano .envChange:
APP_NAME=Laravel
APP_ENV=production
APP_DEBUG=false
APP_URL=https://api.example.com
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD=StrongPasswordGenerate key:
php artisan key:generateRun migration:
php artisan migrate --forceStorage:
php artisan storage:linkPermission:
chown -R www-data:www-data /var/www/api
chmod -R 755 /var/www/api/storageStep 8: Configure Laravel Nginx
Create:
nano /etc/nginx/sites-available/api.example.comPaste:
server {
listen 80;
server_name api.example.com;
root /var/www/api/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}Save.
Enable:
ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/Test:
nginx -tRestart:
systemctl restart nginxStep 9: Install Node.js
Install Node 22:
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install nodejs -yCheck:
node -v
npm -vStep 10: Deploy Next.js Frontend
Create:
mkdir -p /var/www/frontendGo:
cd /var/www/frontendClone:
git clone YOUR_FRONTEND_REPO .Install:
npm installCreate env:
nano .env.productionExample:
NEXT_PUBLIC_API_URL=https://api.example.comBuild:
npm run buildTest:
npm startStop using CTRL+C.
Step 11: Install PM2
npm install pm2 -gStart Next:
pm2 start npm --name frontend -- startSave:
pm2 saveAuto start:
pm2 startupCopy the generated command and run it.
Step 12: Configure Nginx for Next.js
Create:
nano /etc/nginx/sites-available/example.comAdd:
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}Enable:
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/Restart:
nginx -t
systemctl restart nginxStep 13: Add SSL Certificate (HTTPS)
Install Certbot:
apt install certbot python3-certbot-nginx -yFor frontend:
certbot --nginx -d example.com -d www.example.comFor API:
certbot --nginx -d api.example.comTest renewal:
certbot renew --dry-runStep 14: Laravel Queue (If Needed)
If your project uses jobs:
Install supervisor:
apt install supervisor -yCreate:
nano /etc/supervisor/conf.d/laravel-worker.confAdd:
[program:laravel-worker]
command=php /var/www/api/artisan queue:work
directory=/var/www/api
autostart=true
autorestart=true
user=www-dataRestart:
supervisorctl reread
supervisorctl update
supervisorctl start laravel-workerFinal Structure
/var/www
├── api
│ └── Laravel
│
└── frontend
└── Next.jsYour URLs: Frontend: https://example.com Backend API: https://api.example.com
Important VPS Optimization
VPS usually has: 1 CPU 4GB RAM 50GB SSD Recommended:
apt install htop -y
monitor:
htop
enable swap:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfileThis prevents Next.js builds from crashing.
Last updated on 04/08/2026
