Skip to content
Latchkey

CI/CD for a Laravel + Queue Worker with GitHub Actions

Lint, test, and build your Laravel app and queue worker on every push.

A Laravel app dispatches jobs to a queue worker backed by Redis, with MySQL for data. This recipe installs PHP and JS deps, runs Pint and PHPUnit against both services, and builds front-end assets.

What the pipeline does

  • set up PHP and install Composer deps
  • lint with Pint
  • run PHPUnit against MySQL + Redis
  • build assets with npm run build
  • package the app for deploy

The workflow

MySQL and Redis service containers back the test run; QUEUE_CONNECTION=redis exercises the queue. shivammathur/setup-php provides PHP and Composer.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: app_test
        ports: ['3306:3306']
        options: >-
          --health-cmd "mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 5
      redis:
        image: redis:7
        ports: ['6379:6379']
    env:
      DB_HOST: 127.0.0.1
      QUEUE_CONNECTION: redis
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: composer install --no-interaction --prefer-dist
      - run: ./vendor/bin/pint --test
      - run: php artisan migrate --force
      - run: ./vendor/bin/phpunit
      - run: npm ci && npm run build

Caching and speed

Cache Composer with actions/cache on ~/.composer/cache keyed on composer.lock, and cache: npm covers JS deps. The two service containers add startup time; cheaper managed runners such as Latchkey keep frequent runs affordable and auto-retry transient service-startup races.

Deploying

Deploy the app server (php-fpm + nginx or Octane) and run php artisan queue:work as a separate worker process or container. Run php artisan migrate --force as a release step and point both at the same MySQL and Redis.

Key takeaways

  • Back tests with MySQL and Redis service containers.
  • Run queue:work as a separate deployed worker process.
  • Pint --test gates code style without rewriting files in CI.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →