Upgrading Laravel 10 to Laravel 11: Production Server Environment Upgrades (PHP 8.3/Remi/Nginx) on Rocky Linux 9
Prerequisites and Environment Assessment
Before embarking on the Laravel 10 to Laravel 11 upgrade on a production Rocky Linux 9 server, a thorough assessment of the existing environment is paramount. This includes verifying PHP version compatibility, ensuring necessary extensions are available, and understanding the current Nginx and database configurations. Laravel 11 officially requires PHP 8.2 or higher, with PHP 8.3 being the recommended and often default version on recent Rocky Linux 9 installations via Remi’s repository. This guide assumes you are using Remi’s PHP repository for managing your PHP versions.
Verify your current PHP version and enabled extensions. On your server, execute:
php -v php -m
Ensure that extensions critical for your Laravel application (e.g., pdo_mysql, redis, imagick, intl, mbstring, openssl, tokenizer, xml, zip) are loaded. If using Remi’s repository, you can install or update extensions with commands like:
sudo dnf install php-mysqlnd php-redis php-pecl-imagick php-intl php-mbstring php-openssl php-tokenizer php-xml php-zip sudo systemctl restart php-fpm
Confirm your Nginx configuration is robust and serving your Laravel 10 application correctly. Pay attention to the fastcgi_pass directive pointing to your PHP-FPM socket or port, and ensure appropriate buffer sizes and timeouts are set. A typical Nginx server block for Laravel looks like this:
server {
listen 80;
server_name your_domain.com www.your_domain.com;
root /var/www/your_laravel_app/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/www.sock; # Or your PHP-FPM port
fastcgi_read_timeout 300; # Adjust as needed
}
location ~ /\.ht {
deny all;
}
access_log /var/log/nginx/your_laravel_app.access.log;
error_log /var/log/nginx/your_laravel_app.error.log;
}
Upgrading PHP to 8.3 (if necessary)
If your current PHP version is below 8.2, you’ll need to upgrade. Assuming Remi’s repository is already configured, this is straightforward. First, enable the PHP 8.3 module and disable older ones:
sudo dnf module enable php:remi-8.3 -y sudo dnf module disable php:remi-8.2 -y # Or whichever version you are disabling sudo dnf update php\* -y sudo systemctl restart php-fpm sudo systemctl restart nginx
After updating PHP, re-verify your installed extensions using php -m and reinstall any that might have been removed or are incompatible with the new PHP version. It’s also a good practice to check your application’s dependencies for PHP 8.3 compatibility.
Preparing the Laravel Application for Upgrade
Before touching the application code, it’s crucial to back up your project files and database. Then, update your application’s composer.json file. Laravel 11 introduces significant changes, including a simplified directory structure and new configuration loading mechanisms. The primary change for Composer is updating the Laravel framework dependencies.
{
"require": {
"php": "^8.2",
"laravel/framework": "^11.0"
},
"require-dev": {
"laravel/pint": "^1.13",
"nunomaduro/collision": "^7.0"
}
}
Run Composer to update the dependencies. It’s highly recommended to do this in a development or staging environment first.
composer update laravel/framework --no-plugins --no-scripts # Then, to install the updated dependencies and run post-install scripts composer update --no-plugins --no-scripts composer install --optimize-autoloader --no-dev
Laravel 11’s upgrade guide outlines several manual steps. The most significant is the directory structure change. You will need to adapt your application to the new structure, which typically involves moving files from app/Http/Controllers to app/Http/Controllers/Auth (if applicable) and other structural adjustments. Configuration files are now consolidated under config/ and are no longer published by default.
Run the following Artisan commands to generate new configuration files and potentially other necessary files. Note that Laravel 11 uses a new command for generating configuration.
php artisan config:generate php artisan app:name "NewAppName" # If you need to change the app name php artisan make:middleware EnsureTenantHasDatabase # Example for custom middleware
Pay close attention to the .env file. Laravel 11 has a new default .env file. You’ll need to merge your existing environment variables into the new structure, especially for database credentials, cache drivers, and mail configurations. The default config/app.php is now minimal, with most settings managed via environment variables or the new bootstrap/app.php file.
Database Migrations and Schema Changes
Laravel 11 introduces changes to how migrations are handled. The default migration files are now located in database/migrations. If you have custom migration commands or logic, review them for compatibility. Run your migrations to ensure the database schema is up-to-date with the new application structure.
php artisan migrate --force
The --force flag is crucial for production environments to prevent accidental migration runs on the wrong database. Always ensure you have a recent database backup before executing this command.
Nginx and PHP-FPM Configuration Adjustments
With Laravel 11’s potential changes in how it handles requests or its public directory structure (though the default remains public/), it’s wise to review your Nginx configuration. Ensure the root directive still points to the correct directory (usually /var/www/your_laravel_app/public). The try_files directive should also be checked to ensure it correctly directs requests to index.php.
server {
listen 80;
server_name your_domain.com www.your_domain.com;
root /var/www/your_laravel_app/public; # Ensure this is correct
index index.php index.html index.htm;
location / {
# Laravel 11's default public directory structure is still handled by index.php
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/www.sock; # Verify this path
fastcgi_read_timeout 300;
}
# ... other directives ...
}
If you’ve updated PHP, ensure your PHP-FPM configuration (e.g., /etc/php-fpm.d/www.conf) is correctly configured and that the socket path or port matches your Nginx configuration. Restart PHP-FPM and Nginx after any changes.
sudo systemctl restart php-fpm sudo systemctl restart nginx
Testing and Deployment Strategy
Thorough testing is non-negotiable. Deploy the upgraded application to a staging environment that mirrors production as closely as possible. Perform comprehensive functional testing, API testing, and load testing. Pay special attention to areas that might be affected by framework changes, such as routing, middleware, service providers, and any custom Artisan commands.
Monitor logs closely during testing. Check Nginx error logs (/var/log/nginx/error.log and your application-specific error log), PHP-FPM logs, and Laravel’s own logs (storage/logs/laravel.log). Look for any PHP errors, warnings, or unexpected behavior.
For the production deployment, consider a phased rollout or a blue-green deployment strategy if downtime is critical. A typical deployment workflow might involve:
- Placing the server in maintenance mode.
- Pulling the latest code from your version control system.
- Running
composer install --optimize-autoloader --no-dev. - Running database migrations (
php artisan migrate --force). - Clearing and caching configuration and routes (
php artisan config:clear && php artisan route:clear && php artisan config:cache && php artisan route:cache). - Restarting PHP-FPM and Nginx.
- Taking the server out of maintenance mode.
Always have a rollback plan in place. This includes reverting code changes, rolling back database migrations if necessary (though this can be complex and is often avoided by designing forward-compatible migrations), and restoring from backups.
Leave a Reply
You must be logged in to post a comment.