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/composerNginx 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.comCertbot 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/cacheQueue 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 startupDatabase 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