Set Up Laravel Queue on Linux with PM2 & YAML Step-by-Step

When I started using Laravel for web applications, I found that tasks like sending emails or processing large datasets slowed down my app. Laravel Queues solved this by running tasks in the background, and pairing them with PM2, a robust process manager, made managing queue workers a breeze.

In this guide, I’ll show you how I set up Laravel Queue on a Linux server using PM2 with a YAML configuration file for better organization and scalability. This beginner-friendly tutorial is perfect for developers looking to streamline background processing. Let’s dive in!

Step-by-Step Guide to Setting Up Laravel Queue with PM2 Using YAML on a Linux Server

Set Up Laravel Queue on Linux with PM2 & YAML Step-by-Step

Step 1: Connect to Your Linux Server

I begin by connecting to my Linux server via SSH. In my terminal, I run:

ssh username@server-ip

Replace username and server-ip with your server’s credentials. Once logged in, I prepare my server for setup.

Step 2: Update Your Server

To avoid compatibility issues, I update the server’s packages. For Ubuntu or Debian-based systems, I run:

sudo apt update
sudo apt upgrade -y

This ensures my server has the latest software.

Step 3: Verify Laravel and Dependencies

I assume you have a Laravel application in a directory like /var/www/myapp. If not, install Laravel using Composer. I verify Laravel, PHP, Composer, and a database (like MySQL) are installed:

cd /var/www/myapp
php artisan --version

Since PM2 is Node.js-based, I ensure Node.js and npm are installed:

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
node -v
npm -v

Step 4: Install PM2 Globally

I install PM2 globally using npm to manage the Laravel queue worker:

sudo npm install -g pm2

I verify the installation:

pm2 -v

Step 5: Configure Laravel Queue Driver

Laravel supports queue drivers like database, Redis, and Amazon SQS. I use the database driver for simplicity. In my project’s .env file, I set:

nano .env
QUEUE_CONNECTION=database

I save and exit, configuring Laravel to use the database driver for queue jobs.

Step 6: Create the Jobs Table

The database driver requires a jobs table. I generate and run the migration:

php artisan queue:table
php artisan migrate

This creates the jobs table. I ensure my database credentials in .env are correct.

Step 7: Create a Sample Job

To test the queue, I create a job for sending a welcome email:

php artisan make:job SendWelcomeEmail

In app/Jobs/SendWelcomeEmail.php, I add logic in the handle method:

<?php
namespace App\Jobs;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        Mail::to($this->user->email)->send(new \App\Mail\WelcomeEmail($this->user));
    }
}

I configure mail settings in .env (e.g., MAIL_DRIVER=log for testing).

Step 8: Dispatch a Job

I dispatch the job from a controller or route. In a controller:

use App\Jobs\SendWelcomeEmail;
use App\Models\User;

public function create(Request $request)
{
    $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => bcrypt($request->password),
    ]);

    SendWelcomeEmail::dispatch($user);

    return response()->json(['message' => 'User created and email queued']);
}

This queues the job for processing.

Step 9: Create a PM2 YAML Configuration File

Instead of running the queue worker directly, I use a YAML file for better management. In my project directory (/var/www/myapp), I create ecosystem.config.yml:

nano ecosystem.config.yml

I add the following configuration:

apps:
  - name: laravel-queue
    script: artisan
    interpreter: php
    args: queue:work --tries=3
    cwd: /var/www/myapp
    instances: 1
    autorestart: true
    watch: false
    max_memory_restart: 300M
    env:
      APP_ENV: production
    log_file: /var/www/myapp/storage/logs/pm2.log

This configures PM2 to:

  • Run php artisan queue:work with 3 retry attempts.
  • Set the working directory to /var/www/myapp.
  • Use one instance, auto-restart on failure, and limit memory to 300MB.
  • Log output to a file in the Laravel project.

I save and exit. Replace /var/www/myapp with your project path.

Step 10: Start the Queue Worker with PM2

I navigate to my project directory:

cd /var/www/myapp

I start PM2 with the YAML file:

pm2 start ecosystem.config.yml

This launches the queue worker as defined in the YAML file.

Step 11: Save the PM2 Process

To ensure the worker restarts after a server reboot, I save the PM2 process list:

pm2 save

Step 12: Set Up PM2 for System Startup

I configure PM2 to start on server boot:

pm2 startup

This generates a command (e.g., for systemd). I run it, replacing username with my server user:

sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u username --hp /home/username

Step 13: Monitor and Manage with PM2

I manage the queue worker using PM2 commands:

  • View processes:

    pm2 list
    
  • Monitor resources:

    pm2 monit
    
  • View logs:

    pm2 logs laravel-queue
    
  • Restart the worker:

    pm2 restart laravel-queue
    
  • Stop the worker:

    pm2 stop laravel-queue
    

Step 14: Handle Failed Jobs

I set up a failed_jobs table:

php artisan queue:failed-table
php artisan migrate

In .env, I set:

QUEUE_FAILED_DRIVER=database

To retry failed jobs:

php artisan queue:retry all

I check logs in storage/logs/laravel.log or /var/www/myapp/storage/logs/pm2.log for debugging.

Conclusion

Using a YAML configuration file with PM2 to manage Laravel Queue workers has made my life easier. It keeps my queue workers organized, scalable, and reliable, ensuring my Laravel app handles background tasks efficiently. This setup combines Laravel’s powerful queue system with PM2’s robust process management, all configured cleanly via YAML. Follow these steps, and you’ll have a seamless queue system up and running. Try it out and let me know how it works for you!

Frequently Asked Questions(FAQs)

Q1: Why use a YAML file with PM2 for Laravel Queues?
A: A YAML file makes it easier to manage and scale queue workers. I can define multiple workers, set memory limits, and configure logs in one place, improving maintainability.

Q2: Can I run multiple queue workers with PM2?
A: Yes, I can increase instances in the YAML file (e.g., instances: 4) to run multiple workers, balancing load for high-traffic apps.

Q3: What if my queue worker fails?
A: PM2’s autorestart: true in the YAML file restarts the worker automatically. I check logs with pm2 logs laravel-queue to diagnose issues.

Q4: Can I use Redis or SQS with this setup?
A: Yes, I can change QUEUE_CONNECTION to redis or sqs in .env. The PM2 YAML configuration remains the same for managing the worker.

Q5: Is PM2’s YAML configuration free to use?
A: Yes, PM2’s core features, including YAML configuration, are free. Paid features for advanced monitoring are optional and not needed for this setup.


You might also like :

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS