Skip to main content
Laravel, shipping fast.

Chapter 13

DevOps & Infrastructure

Julian Beaujardin

Your amazing API doesn't matter if it's not in production. Deployment is where theory meets reality.

This chapter is short but important. We cover:

  1. CI/CD: Automated testing on every push
  2. Deployment: Getting code from your laptop to the internet
  3. Monitoring: Knowing when things break
  4. Scaling: Handling growth

These are the unglamorous but essential parts of shipping software.

If you're using Laravel Herd or Docker locally, you're already 80% of the way to production. The jump from local to production is just deployment configuration.

CI/CD Pipeline

The moment you push code, it should be automatically tested. The moment tests pass, it should deploy. No manual steps. No "I forgot to run tests."

# .github/workflows/test-and-deploy.yml
name: Test & Deploy

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_DATABASE: test_db
          MYSQL_ROOT_PASSWORD: secret
      redis:
        image: redis:7-alpine

    steps:
      - uses: actions/checkout@v3

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.4
          extensions: mysql, redis

      - name: Install Dependencies
        run: composer install

      - name: Copy .env.example to .env.test
        run: cp .env.example .env.test

      - name: Generate Key
        run: php artisan key:generate --env=testing

      - name: Run Tests
        run: php artisan test

      - name: Upload Coverage
        uses: codecov/codecov-action@v3

CI/CD removes friction. Tests run automatically. Humans don't have to remember. The system enforces quality.

Simple Deployment

You don't need a complicated deployment process. Start simple:

#!/bin/bash
# deploy.sh

# Pull latest code
git pull origin main

# Install/update dependencies
composer install --no-dev

# Run migrations
php artisan migrate --force

# Clear caches
php artisan optimize

# Restart queue workers
php artisan queue:restart

# Done!
echo "Deployment complete"

Push to main → tests run → if passing, deploy. That's it.

Monitoring in Production

You can't fix what you don't see. Deploy monitoring with your app:

Route::get('/health', function () {
    return [
        'status' => 'ok',
        'database' => DB::connection()->getPdo() ? 'ok' : 'down',
        'cache' => Cache::get('test') !== null ? 'ok' : 'down',
        'queue' => Queue::size() < 1000 ? 'ok' : 'warning',
    ];
});

Point your monitoring tool at /health. If it's not ok, alert your team.

Chapter 13 Summary

Deployment is not magic. It's just:

  1. Push code
  2. Run tests
  3. If tests pass, deploy
  4. Monitor to catch issues
  5. Rollback if needed

Start simple. Automate what you can. Monitor everything. Scale when needed, not before.