title: Setup CI/CD for Laravel with GitHub Actions summary: Automate testing and deployment of Laravel apps using GitHub Actions. date: 2024-06-15 tags: [Laravel, GitHub Actions, CI/CD, DevOps, Automation]

Setup CI/CD for Laravel with GitHub Actions

Continuous Integration and Continuous Deployment (CI/CD) are crucial practices in modern web development. Automating the testing and deployment of your Laravel applications increases reliability, efficiency, and development speed. In this post, we'll walk through setting up a robust CI/CD workflow for Laravel using GitHub Actions.

Why GitHub Actions for Laravel?

GitHub Actions integrates seamlessly with your repositories, making it easy to automate build, test, and deployment pipelines without external services. With a few YAML config files, you can:

  • Run your PHPUnit tests on every push or pull request.
  • Lint your code and check code style.
  • Deploy to production or staging environments automatically.

Let's get started!


Prerequisites

  • Laravel application in a GitHub repository.
  • Composer dependencies committed (or manageable via composer install).
  • Test suite (PHPUnit) setup in Laravel.
  • Deployment method (e.g., SSH, or platforms like Laravel Forge, Envoyer, etc.).
  • GitHub secret access for sensitive credentials.

1. Configure Your GitHub Actions Workflow

Create a .github/workflows/ci-cd.yml file in your repository:

name: Laravel CI/CD

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

jobs:
  laravel-tests:

    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: laravel
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3

    steps:
    - uses: actions/checkout@v4

    - name: Set up PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: 8.2
        extensions: mbstring, bcmath, mysql
        ini-values: post_max_size=256M, upload_max_filesize=256M

    - name: Copy .env
      run: php -r "file_exists('.env') || copy('.env.example', '.env');"

    - name: Install Composer dependencies
      run: composer install --prefer-dist --no-progress --no-interaction

    - name: Generate app key
      run: php artisan key:generate

    - name: Setup database
      env:
        DB_HOST: 127.0.0.1
        DB_DATABASE: laravel
        DB_USERNAME: root
        DB_PASSWORD: root
      run: |
        php artisan migrate --force

    - name: Run tests
      env:
        DB_HOST: 127.0.0.1
        DB_DATABASE: laravel
        DB_USERNAME: root
        DB_PASSWORD: root
      run: php artisan test

  deploy:
    needs: laravel-tests
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Deploy to Production (example with SSH)
      uses: appleboy/ssh-action@v0.1.10
      with:
        host: ${{ secrets.PRODUCTION_HOST }}
        username: ${{ secrets.PRODUCTION_USER }}
        key: ${{ secrets.PRODUCTION_SSH_KEY }}
        port: 22
        script: |
          cd /var/www/your-laravel-project
          git pull origin main
          composer install --no-interaction --prefer-dist --optimize-autoloader
          php artisan migrate --force
          php artisan cache:clear
          php artisan config:cache

2. Breakdown of the Workflow

  • Triggers: The workflow runs on pushes and pull requests to the main branch.
  • Jobs:
    • laravel-tests: Installs dependencies, prepares the database, generates the app key, runs migrations, and executes the test suite.
    • deploy: Runs only after tests are successful and on a push to main. Uses SSH (via the appleboy/ssh-action) to connect to your production server, pull new changes, install dependencies, run migrations, and optimize your app.

Note: Adjust deployment steps to match your environment (e.g., cd path, deployment scripts).


3. Setting Up GitHub Secrets

For secure deployment, store sensitive information as GitHub Secrets:

  • PRODUCTION_HOST: Your server's IP/domain.
  • PRODUCTION_USER: SSH user.
  • PRODUCTION_SSH_KEY: Private SSH key for authentication.

Go to your repo → SettingsSecrets and variablesActionsNew repository secret.


4. Customizations & Best Practices

  • Add code quality checks: Use tools like PHPStan or Laravel Pint as extra steps.
  • Use environment-specific workflows: You can extend this pattern to include staging, QA, or feature branch previews.
  • Notifications: Integrate Slack, email, or other notifications for failed builds or deployments.

5. Troubleshooting Tips

  • Ensure all necessary PHP extensions are installed.
  • Your server should allow SSH connections from GitHub Actions IPs.
  • Permissions for your SSH key and repo need to be correct.
  • Manage APP_KEY, .env, and any other environment variables properly on your server.

Conclusion

With GitHub Actions, setting up CI/CD for your Laravel projects is straightforward and powerful. This automation ensures your code is always tested and deployed reliably with minimal manual intervention. Continuous improvement of your workflow will make your development and deployment processes even more robust over time.

Happy automating!


Further Reading: