Laravel Production Deployment Guide: From Local to Linux Server
Learn how to execute a secure and reliable laravel production deployment on a Linux server using Nginx, PHP-FPM, and automated shell scripts.
On this page
Executing a successful laravel production deployment requires moving away from local development shortcuts and configuring a robust Linux environment. When transitioning your application from a local machine to a production server, developers often run into permission errors, exposed environment variables, and unoptimized queues. This hands-on guide walks through setting up a production-ready LEMP stack (Linux, Nginx, MySQL/PostgreSQL, PHP-FPM) and automating your deployment workflow.
Before pushing your application live, make sure your underlying infrastructure is properly secured and optimized. If you are starting with a fresh virtual private server, follow a standard Linux Server Administration Checklist: Essential Steps for Ubuntu, Debian, and AlmaLinux to lock down SSH access, configure firewalls, and set up system time synchronization.
Preparing the Linux Server Environment
To run a modern Laravel application efficiently, your server needs specific PHP extensions and a secure web root. First, update your package repository and install PHP along with the required extensions for database connectivity and string manipulation.
Run the following commands on an Ubuntu or Debian server:
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php8.2-fpm php8.2-cli php8.2-mbstring php8.2-xml php8.2-bcmath php8.2-curl php8.2-zip php8.2-mysql unzip git nginx
Next, configure PHP-FPM pool settings to handle incoming requests efficiently. Edit your pool configuration file, typically located at /etc/php/8.2/fpm/pool.d/www.conf, and adjust process manager settings depending on your server RAM availability. Ensure that your web user matches the system user who owns the project files to prevent permission mismatches.
Configuring Nginx for Laravel
Nginx must be explicitly configured to route all incoming HTTP requests through Laravel's single entry point, public/index.php. Create a new virtual host configuration file inside /etc/nginx/sites-available/ for your domain.
Here is a production-tested Nginx server block:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
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 ~ /\.(?!well-known).* {
deny all;
}
}
Enable this site by creating a symbolic link to sites-enabled, test your configuration syntax with sudo nginx -t, and restart Nginx.
Setting Up Database and Environment Variables
Never commit your .env file into version control. Instead, upload your production .env file manually or inject it via your CI/CD pipeline. Generate a secure application key directly on the server:
php artisan key:generate --force
Set your database credentials, cache drivers, and session drivers in the production .env file:
APP_NAME=Laravel
APP_ENV=production
APP_DEBUG=false
APP_URL=https://example.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=production_db
DB_USERNAME=db_user
DB_PASSWORD="secure_random_password"
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
Using Redis for caching, sessions, and queues drastically improves response times under high traffic loads. Make sure your server has the PhpRedis extension installed.
Automating the Deployment Script
A reliable laravel production deployment should be repeatable and automated. Instead of running manual commands over SSH every time you push code, create a deployment shell script that handles code pulling, dependency installation, and cache clearing.
Create a deploy.sh script in your project root:
#!/bin/bash
set -e
echo "Starting deployment..."
# Pull latest code
git pull origin main
# Install composer dependencies without dev packages
composer install --no-dev --optimize-autoloader --no-interaction
# Run database migrations
php artisan migrate --force
# Clear and cache configurations
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Restart queue workers
php artisan queue:restart
echo "Deployment finished successfully!"
Make the script executable using chmod +x deploy.sh. If you need to manage your server infrastructure or balance workloads across different setups, understanding underlying web server performance tunings like those covered in our Nginx vs Apache Performance Tuning Guide will help you squeeze maximum speed out of your LEMP stack.
Managing Background Queues with Supervisor
Laravel applications heavily rely on background jobs for sending emails, processing uploads, and handling third-party API requests. To ensure your queue workers run continuously without crashing, configure Supervisor.
Install Supervisor on your Linux server:
sudo apt install supervisor
Create a new configuration file at /etc/supervisor/conf.d/laravel-worker.conf:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/example.com/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killsig=QUIT
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/example.com/storage/logs/worker.log
stopwaitsecs=3600
Update Supervisor to recognize the new worker and start the processes:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
Conclusion
Proper laravel production deployment safeguards your application data, speeds up response times, and prevents downtime during updates. By combining a hardened LEMP stack, Nginx URL routing, strict environment configurations, and automated deployment scripts, your Laravel application will run reliably under heavy production traffic.
Frequently asked questions
What is the recommended PHP version for modern Laravel applications?
You should use PHP 8.2 or PHP 8.3 for optimal performance, security support, and full compatibility with the latest Laravel release components.
Why use Supervisor for Laravel queues?
Supervisor runs as a background process manager that automatically restarts your artisan queue:work commands if they crash or if the server reboots.
Should the vendor folder be committed to Git for production?
No. You should run composer install --no-dev --optimize-autoloader directly on the server during the deployment pipeline rather than tracking vendor files in version control.