Back to Blog
Lesson 43 of the Intermediate Laravel: Real-World Application Patterns course
LaravelJune 26, 20264 min read

Deploying Laravel Applications: A Production-Ready Guide

Master deployment for your Laravel project board. Learn how to optimize for production, configure web servers, and automate your release pipeline.

Laraveldeploymentdevopsproductionlinuxphpbackend

Previously in this course, we covered Environment and Configuration Management in Laravel. Now that your project board's configuration is decoupled from your code, it’s time to take your application live.

Deployment is the bridge between your local development environment and your users. A "production-ready" application isn't just about code that works; it's about a resilient, performant, and secure infrastructure. In this lesson, we’ll move beyond simple file uploads and establish a professional deployment workflow.

Optimizing for Production

Before moving code to a server, you must strip away all developer-centric overhead. Laravel ships with several commands designed specifically for this purpose. When running in production, you should always execute the following:

  • Configuration Caching: php artisan config:cache combines all your configuration files into a single file, significantly reducing disk I/O.
  • Route Caching: php artisan route:cache compiles your routes/web.php and routes/api.php files, speeding up request routing.
  • View Caching: php artisan view:cache compiles your Blade templates into plain PHP code, removing the need for runtime parsing.

Warning: Never run these commands in your local development environment. If you do, changes to your .env or route files won't take effect until you clear the cache with php artisan optimize:clear.

Configuring the Web Server

Laravel requires a web server (typically Nginx or Apache) to handle incoming requests and pass them to the PHP-FPM process. For our project board, we assume an Nginx setup.

A production Nginx configuration must point to the public/ directory and ensure that all non-existent files are routed to index.php. Here is the critical location block for your site:

NGINX
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

This configuration ensures your API endpoints and routes work correctly. Ensure your APP_ENV is set to production and APP_DEBUG is false in your server's environment variables to prevent leaking sensitive stack traces to users. See our guide on Preparing for Production: Laravel Optimization and Security for a deeper dive into hardening your settings.

Automating Deployments

Manual FTP uploads are a recipe for disaster. Professional deployment relies on automation, typically using tools like Laravel Forge, Envoyer, or GitHub Actions.

For our project board, we will use a "git-pull" deployment strategy. Your production server should have an SSH key added to your repository's "Deploy Keys." Your deployment script should look like this:

  1. Pull latest code: git pull origin main
  2. Install dependencies: composer install --no-dev --optimize-autoloader
  3. Run migrations: php artisan migrate --force
  4. Clear/Update caches: php artisan optimize
  5. Restart workers: php artisan queue:restart

The --force flag on migrations is critical; Laravel prevents running migrations in production by default to protect your data.

Hands-on Exercise: The Deployment Script

Create a file named deploy.sh in your project root. Write a script that executes the steps mentioned above, adding a check to ensure the application isn't in maintenance mode before starting. Use php artisan down at the start of your script and php artisan up at the end to ensure your users don't interact with the app during the migration process.

Common Pitfalls

  • Forgetting the Queue Worker: Most developers remember the web server but forget that the queue worker (the process running your background jobs) also needs to be restarted after a deployment. Always use php artisan queue:restart to force workers to pick up the new code.
  • Permissions Issues: Ensure your storage/ and bootstrap/cache/ directories are writable by the web server user (usually www-data). If they aren't, your logs won't write and your app will crash.
  • Ignoring Database Migrations: As your application grows, you'll need Laravel Migrations for Blue-Green Deployments: A Practical Guide to ensure you don't lock your database tables during high-traffic updates.

Recap

Deploying is a discipline, not a one-time event. By caching your configuration and routes, configuring Nginx to handle the public/ directory correctly, and automating your deployment script, you ensure your project board is stable. Remember: automate everything, keep your dependencies clean, and always monitor your logs. If you run into issues, refer back to Logging and Monitoring: Mastering Laravel Production Debugging to diagnose the root cause.

Up next: We will dive into Database Indexing Strategies to ensure your project board remains performant as your task list grows.

Similar Posts