Back to Blog
DevOpsAug 20, 202610 min read

Deploying Laravel Applications on a VPS

A practical walkthrough for deploying Laravel applications on a VPS with Nginx, SSL, PM2, and basic server hardening.

Why VPS Deployment

VPS deployment gives you full control over your server environment. Unlike shared hosting, you can configure Nginx, PHP-FPM, Redis, and queue workers exactly as your application needs.

For production Laravel applications, I typically deploy to a VPS running Ubuntu with Nginx.

Server Setup

Start with a fresh Ubuntu server:

# Update system
sudo apt update && sudo apt upgrade -y

# Install PHP and required extensions
sudo apt install php8.2-fpm php8.2-mysql php8.2-xml php8.2-mbstring php8.2-curl php8.2-zip php8.2-redis -y

# Install Nginx
sudo apt install nginx -y

# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Nginx Configuration

Create a server block for your Laravel application:

server {
    listen 80;
    server_name your-domain.com;
    root /var/www/your-app/public;

    index index.php;

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

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

    location ~ /\. {
        deny all;
    }
}

SSL with Certbot

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d your-domain.com

Certbot automatically configures Nginx for HTTPS and sets up certificate renewal.

Environment and Permissions

cd /var/www/your-app
cp .env.example .env
php artisan key:generate

# Set permissions
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache

Queue Workers with PM2

If your app uses queues, run workers with PM2:

pm2 start artisan --name="queue-worker" -- queue:work --sleep=3 --tries=3
pm2 save
pm2 startup

Database Setup

sudo mysql -u root
CREATE DATABASE your_app;
CREATE USER 'your_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON your_app.* TO 'your_user'@'localhost';

Then run migrations:

php artisan migrate --force

Key Takeaways

  • Use Nginx with PHP-FPM for production Laravel
  • Always enable SSL with Certbot
  • Set proper file permissions for storage and cache
  • Use PM2 for queue workers and process management
  • Keep your `.env` file secure and never commit it