Muhammad Manamil on November 10, 2025
Upgrading a production Laravel application can be stressful — new framework versions bring performance improvements and helpful features, but they can also introduce breaking changes. Laravel 12 modernizes routing, tightens minimum PHP requirements, updates the default frontend tooling, and removes/deprecates several helpers. If you plan and execute the upgrade carefully, you can avoid downtime and fix most issues quickly.
If you want to see the guidelines for installing Laravel, click here.
This guide walks you through a safe, step-by-step upgrade process from Laravel 11 (or earlier) to Laravel 12, highlights the most common problems developers face after upgrading, and provides concrete, copy-and-paste fixes. Follow these steps on a staging environment first, then apply them to production once everything is validated.
Quick checklist before you start
Read the official upgrade guide and CHANGELOG for Laravel 12 to identify breaking changes specific to your app (packages, helpers, events).
Update your composer.json requirement for laravel/framework:
"require": {
"laravel/framework": "^12.0",
// ... other deps
}
3. Check third-party packages: ensure they support Laravel 12 or have new versions available.
Laravel 12 requires PHP 8.2 or higher. Verify and upgrade PHP on your environment:
Check current PHP version
php -v
Ubuntu example (install PHP 8.2)
sudo apt update
sudo apt install php8.2 php8.2-fpm php8.2-cli php8.2-mbstring php8.2-xml php8.2-curl php8.2-zip php8.2-gd
If you are using managed hosting (Forge, Ploi, Vapor, shared hosting), confirm PHP 8.2 availability and select it.
On your feature/staging branch:
composer update
composer install --no-dev --optimize-autoloader
Fix any dependency conflicts by upgrading or replacing incompatible composer packages. If composer update fails, read the error message and update problematic packages in composer.json (or contact package maintainers).
Before changing code, run your test suite and static analysis tools:
php artisan test
./vendor/bin/phpstan analyse
./vendor/bin/pint # if using Laravel Pint
Fix failing tests that point to deprecated behavior or changed interfaces.
Laravel 12 introduces a new pattern for registering route files in some project starter templates. If you used custom bootstrap code or a micro framework style, update it to the withRouting pattern where applicable.
Example new pattern:
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
console: __DIR__.'/../routes/console.php'
);
If your project still uses older routing group patterns, migrate to the current approach. Also search for custom $app->router->group() calls that might require updating.
Laravel organizes models under app/Models by default. If your models live elsewhere or namespaces are incorrect:
Ensure model files have the correct namespace:
namespace App\Models;
2. Regenerate Composer autoload files:
composer dump-autoload
If you moved files or renamed classes, update any references (type hints, factories, relationships).
Search your codebase for known removed helpers or methods (examples may include some previously available string or collection helpers). Replace with recommended alternatives from the Laravel docs or Illuminate helper classes.
Example
If you get:
Call to undefined method Str::containsAll()
Replace with a custom helper or chain of Str::contains() calls, or update to the new method recommended in the upgrade notes.
Laravel 12 uses Vite by default for asset bundling. After upgrade you should reinstall node modules and rebuild:
npm ci
# or
npm install
# development:
npm run dev
# production build:
npm run build
If you encounter “Failed to resolve module” errors, check your vite.config.js and resources/js/resources/css entry points for renamed paths.
After upgrading, you may need to recreate the public storage link.
Remove old link (if present)
rm -rf public/storage
Create symlink
php artisan storage:link
On some shared hosts, symlink creation may be restricted. In that case either enable symlinks in control panel or use a deployment step to copy files instead of linking.
Always clear caches after major upgrades to avoid stale cached configs and compiled classes:
php artisan optimize:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
composer dump-autoload -o
Then warm caches (optional):
php artisan config:cache
php artisan route:cache
Note: only cache routes if your app does not rely on runtime route modifications (closures or dynamic route generation).
Laravel version changes can affect queue workers. Restart queue workers and verify job serialization compatibility:
php artisan queue:restart
If you use serialized or versioned job classes, ensure __serialize()/__unserialize() compatibility or migrate job payloads before starting workers.
composer install --no-dev --optimize-autoloader
php artisan migrate --force # if DB migrations are required
php artisan storage:link
php artisan optimize:clear
php artisan config:cache
php artisan route:cache
npm ci && npm run build # if assets are built on server
4. Monitor logs and error reporting tools (Sentry, Bugsnag, Papertrail) for a few hours after deployment.
Q1 — Should I upgrade immediately?
A: Not unless you need Laravel 12 features or security fixes. Upgrade on a controlled schedule — test on staging first, and ensure package compatibility.
Q2 — Do I need to update PHP on both dev and prod?
A: Yes. PHP 8.2 is required. Update local dev, CI, staging, and production to avoid environment mismatches.
Q3 — My php artisan storage:link shows permission or symlink errors. What now?
A: Remove the existing public/storage folder/link, then run php artisan storage:link. If still blocked, check file permissions and hosting control panel settings (some shared hosts block symlinks). As a fallback, copy storage/app/public to public/storage during deployment.
Q4 — After upgrading, my assets are missing.
A: Rebuild assets with npm install / npm ci and npm run build. Ensure vite.config.js entry points match your resources/ paths and that @vite directive is used in your Blade layout.
Q5 — Should I cache config and routes after upgrading?
A: Yes in production for performance, but only after verifying everything works. Remember to run php artisan optimize:clear if issues appear and only route:cache if your routes are static (no closures).
Q6 — Third-party packages not compatible with Laravel 12 — what should I do?
A: Check for package updates or forks that support Laravel 12. If none exist, consider replacing the package with an actively maintained alternative or implement the needed functionality in-house.
Q7 — Any special advice for Laravel Vapor or serverless environments?
A: Vapor usually supports the latest Laravel versions quickly, but always confirm Vapor CLI and runtime PHP versions in the Vapor docs. Run a full Vapor deployment on a test environment before production.
Q8 — How do I rollback if something goes wrong?
A: Use your version control revert/rollback procedures and database backups. If you used zero-downtime deploys, roll back via your deploy tooling (Forge, Envoyer, GitHub Actions). Ensure DB migrations are reversible or use backups.
November 06 2025
How to Install Free SSL on Ubuntu Server Using Certbot (Step-by-Step 2026 Guide)Learn how to install a free SSL certificate on your Ubuntu server using Certbot and Let’s Encrypt. This step-by-step 2026 guide will help you secure your website with HTTPS, boost trust, and improve SEO — all without paying a single rupee
November 10 2025
Laravel 12 – Fixing storage:link Asset ErrorFacing the “storage:link” asset error in Laravel 12? This guide walks you through the exact fixes for missing symlinks, incorrect file paths, and permission issues. Learn how to reconnect your public/storage link, adjust filesystem settings, and make uploaded files publicly accessible on both VPS and shared hosting environments.
© 2025 — Revision. All Rights Reserved.