Skip to content

Deployment

This guide covers a typical VPS production setup:

  • exchangepro.com → Nuxt (Node)
  • api.exchangepro.com → Laravel (PHP-FPM + Nginx)

Pre-deployment checklist

  • [ ] APP_DEBUG=false on backend
  • [ ] APP_KEY generated
  • [ ] Migrations run on production database
  • [ ] FRONTEND_URL and API_URL set correctly
  • [ ] CORS and Sanctum domains configured
  • [ ] SSL certificates installed
  • [ ] Cron entry for Laravel scheduler (* * * * * … schedule:run)
  • [ ] Queue: sync or Supervisor running queue:work if QUEUE_CONNECTION=database
  • [ ] Mail SMTP working

Backend — Nginx + PHP-FPM

Document root

nginx
server {
    listen 443 ssl http2;
    server_name api.exchangepro.com;

    root /var/www/exchangepro/backend/public;
    index index.php;

    ssl_certificate     /etc/letsencrypt/live/api.exchangepro.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.exchangepro.com/privkey.pem;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    client_max_body_size 12M;
}

client_max_body_size helps proof file uploads (5 MB limit per file in app).

Optimize Laravel

bash
cd /var/www/exchangepro/backend
composer install --no-dev --optimize-autoloader
php artisan config:cache
php artisan route:cache
php artisan view:cache

Frontend — Node SSR

Build on server (or CI)

bash
cd /var/www/exchangepro/frontend
npm ci
npm run build

systemd service example

/etc/systemd/system/exchangepro-frontend.service:

ini
[Unit]
Description=ExchangePro Nuxt SSR
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/exchangepro/frontend
Environment=HOST=127.0.0.1
Environment=PORT=3000
Environment=FRONTEND_URL=https://exchangepro.com
Environment=API_URL=https://api.exchangepro.com
ExecStart=/usr/bin/node .output/server/index.mjs
Restart=on-failure

[Install]
WantedBy=multi-user.target
bash
sudo systemctl enable --now exchangepro-frontend

Nginx reverse proxy to Nuxt

nginx
server {
    listen 443 ssl http2;
    server_name exchangepro.com www.exchangepro.com;

    ssl_certificate     /etc/letsencrypt/live/exchangepro.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/exchangepro.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Alternative: PM2

bash
npm install -g pm2
cd frontend
FRONTEND_URL=https://exchangepro.com API_URL=https://api.exchangepro.com \
  pm2 start .output/server/index.mjs --name exchangepro-web
pm2 save

File uploads & persistence

Ensure these survive deploys and are backed up:

text
backend/public/transaction-proofs/
backend/public/images/

Do not wipe public/images on deploy if it contains production uploads.

Admin cache clear

Admins can clear caches from Admin → Extra → Cache, or run:

bash
php artisan optimize:clear

Zero-downtime tips

  • Put site in maintenance: php artisan down during DB migrations
  • Run php artisan migrate --force before switching traffic
  • Rebuild frontend after env changes

Shared hosting note

If your host only supports PHP (no Node):

  • Host API on subdomain
  • Build Nuxt locally and host SSR on Vercel, Netlify, Railway, or a small VPS
  • Point API_URL to PHP backend

Pure cPanel without Node cannot run the default Nuxt SSR output.

Need help? support@xorinlab.com · Website: xorinlab.com