Deploying Laravel Applications on Debian Servers: Nginx, PHP-FPM, and SSL Configuration
Deploying Laravel Applications on Debian Servers: Nginx, PHP-FPM, and SSL Configuration
Production Laravel deployments require proper web server configuration, PHP-FPM tuning, and SSL setup. Here's my complete guide to deploying Laravel applications on Debian servers with Nginx and Let's Encrypt.
🎯 Production Requirements
A production Laravel deployment needs:
- Web server (Nginx) for handling requests
- PHP-FPM for processing PHP
- SSL certificates for HTTPS
- Optimized configuration for performance
- Security hardening for protection
📦 Installation
1. Install Nginx
```bash sudo apt update sudo apt install nginx
Start and enable
sudo systemctl start nginx sudo systemctl enable nginx ```
2. Install PHP-FPM
```bash sudo apt install php8.2-fpm php8.2-cli php8.2-mysql php8.2-xml \ php8.2-mbstring php8.2-curl php8.2-zip php8.2-gd php8.2-bcmath
Verify installation
php -v ```
3. Install Composer
```bash curl -sS https://getcomposer.org/installer | php sudo mv composer.phar /usr/local/bin/composer ```
⚙️ Nginx Configuration
1. Create Site Configuration
```bash sudo nano /etc/nginx/sites-available/ameylokare.com ```
```nginx server { listen 80; listen [::]:80; server_name ameylokare.com www.ameylokare.com; root /var/www/ameylokare.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; fastcgi_hide_header X-Powered-By; }
location ~ /\.(?!well-known).* { deny all; } } ```
2. Enable Site
```bash sudo ln -s /etc/nginx/sites-available/ameylokare.com /etc/nginx/sites-enabled/ sudo nginx -t # Test configuration sudo systemctl reload nginx ```
🔧 PHP-FPM Optimization
1. Pool Configuration
```bash sudo nano /etc/php/8.2/fpm/pool.d/www.conf ```
```ini [www] user = www-data group = www-data listen = /run/php/php8.2-fpm.sock listen.owner = www-data listen.group = www-data
; Process management pm = dynamic pm.max_children = 50 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20 pm.max_requests = 500
; Performance pm.process_idle_timeout = 10s request_terminate_timeout = 300s ```
2. PHP Configuration
```bash sudo nano /etc/php/8.2/fpm/php.ini ```
```ini memory_limit = 256M upload_max_filesize = 20M post_max_size = 20M max_execution_time = 300 max_input_time = 300
; OPcache (for production) opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.revalidate_freq=2 opcache.fast_shutdown=1 ```
3. Restart PHP-FPM
```bash sudo systemctl restart php8.2-fpm ```
🔒 SSL with Let's Encrypt
1. Install Certbot
```bash sudo apt install certbot python3-certbot-nginx ```
2. Obtain Certificate
```bash sudo certbot --nginx -d ameylokare.com -d www.ameylokare.com ```
Certbot will:
- Obtain SSL certificate
- Configure Nginx automatically
- Set up auto-renewal
3. Auto-Renewal
Certbot creates a cron job automatically. Test renewal:
```bash sudo certbot renew --dry-run ```
🚀 Laravel Deployment
1. Clone Repository
```bash cd /var/www sudo git clone https://github.com/username/repo.git ameylokare.com sudo chown -R www-data:www-data ameylokare.com ```
2. Install Dependencies
```bash cd /var/www/ameylokare.com composer install --no-dev --optimize-autoloader npm ci --production npm run build ```
3. Configure Environment
```bash cp .env.example .env php artisan key:generate nano .env # Configure database, mail, etc. ```
4. Run Migrations
```bash php artisan migrate --force ```
5. Optimize
```bash php artisan config:cache php artisan route:cache php artisan view:cache ```
6. Set Permissions
```bash sudo chown -R www-data:www-data /var/www/ameylokare.com sudo chmod -R 755 /var/www/ameylokare.com sudo chmod -R 775 /var/www/ameylokare.com/storage sudo chmod -R 775 /var/www/ameylokare.com/bootstrap/cache ```
🔐 Security Hardening
1. Firewall
```bash sudo ufw allow 'Nginx Full' sudo ufw allow OpenSSH sudo ufw enable ```
2. Fail2ban
```bash sudo apt install fail2ban sudo systemctl enable fail2ban ```
3. Nginx Security Headers
```nginx add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; ```
4. Hide PHP Version
```ini ; /etc/php/8.2/fpm/php.ini expose_php = Off ```
⚡ Performance Optimization
1. Enable Gzip
```nginx gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss; ```
2. Browser Caching
```nginx location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; } ```
3. OPcache
Already configured in php.ini. Verify:
```bash php -i | grep opcache ```
📊 Monitoring
1. Nginx Status
```nginx location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } ```
2. PHP-FPM Status
```nginx location ~ ^/php-fpm-status$ { fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } ```
3. Log Monitoring
```bash
Nginx access logs
sudo tail -f /var/log/nginx/access.log
Nginx error logs
sudo tail -f /var/log/nginx/error.log
PHP-FPM logs
sudo tail -f /var/log/php8.2-fpm.log ```
🔄 Deployment Script
```bash #!/bin/bash
deploy.sh
set -e
APP_DIR="/var/www/ameylokare.com" cd "$APP_DIR"
Pull latest code
git pull origin main
Install dependencies
composer install --no-dev --optimize-autoloader npm ci --production npm run build
Run migrations
php artisan migrate --force
Clear and cache
php artisan config:cache php artisan route:cache php artisan view:cache
Set permissions
sudo chown -R www-data:www-data "$APP_DIR" sudo chmod -R 755 "$APP_DIR" sudo chmod -R 775 "$APP_DIR/storage" sudo chmod -R 775 "$APP_DIR/bootstrap/cache"
Reload services
sudo systemctl reload php8.2-fpm sudo systemctl reload nginx
echo "Deployment completed!" ```
💡 Real-World Example
I deployed a Laravel application handling 50,000+ requests/day:
1. Nginx configured with gzip and caching 2. PHP-FPM tuned for 50 concurrent workers 3. OPcache enabled for 10x faster execution 4. SSL via Let's Encrypt with auto-renewal 5. Security headers and firewall configured
Result: Sub-100ms response times, 99.9% uptime, A+ SSL rating.
🎓 Key Takeaways
- Nginx is fast and efficient for Laravel
- PHP-FPM tuning is crucial for performance
- OPcache dramatically improves speed
- SSL is essential and easy with Let's Encrypt
- Security headers protect against common attacks
- Monitoring helps identify issues early
Conclusion
Proper deployment configuration is essential for production Laravel applications. With Nginx, optimized PHP-FPM, SSL, and security hardening, you can build reliable, fast, and secure applications that scale.