CI/CD · Git workflow

CI/CD for Laravel: Git workflow & zero-downtime deploys

By · Last updated: · free to read, no paywall

The gap between "it works on my machine" and "it deploys itself safely" is smaller than ever. This guide gives you a Git workflow that scales down to a team of one, a copy-paste CI pipeline, and the zero-downtime deployment patterns that make Friday releases boring.

In this guide
  1. Why pipelines pay off (even solo)
  2. A Git workflow that scales down
  3. The CI pipeline, copy-paste ready
  4. Zero-downtime deployment options
  5. After the deploy
  6. Migrations & rollback strategy
  7. FAQ

Why pipelines pay off (even solo)

CI/CD isn't enterprise ceremony — it's the cheapest insurance a codebase can buy:

A Git workflow that scales down

Skip git-flow unless you ship boxed releases. For web apps, trunk-based with short-lived branches wins:

The CI pipeline, copy-paste ready

Four stages, each failing fast: style, static analysis, tests, security audit. Here's a complete GitHub Actions workflow for a Laravel app (drop it in .github/workflows/ci.yml):

name: CI

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.4'
          extensions: mbstring, xml, curl, zip, intl, pdo_sqlite
          coverage: none

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

      - name: Prepare environment
        run: |
          cp .env.example .env
          php artisan key:generate

      - name: Code style (Pint)
        run: vendor/bin/pint --test

      - name: Static analysis (Larastan)
        run: vendor/bin/phpstan analyse --memory-limit=1G

      - name: Tests (Pest)
        run: php artisan test --parallel

      - name: Security audit
        run: composer audit

Notes worth stealing:

Zero-downtime deployment options

Zero-downtime means: build the new release next to the old one, swap atomically, restart workers. Three ways to get it:

1. Webhook push-to-deploy (recommended default)

Your Git host calls a webhook on push; the server builds a new release in releases/, runs composer install, migrate --force and caches, swaps the current symlink and restarts queue workers. This is exactly what Cipi configures automatically when you connect GitHub or GitLab to an app — deploy keys, webhook, releases and symlink swap included, plus Node asset builds on deploy and pre-deploy database snapshots in Cipi 5. Setup cost: one cipi app create.

2. CI-driven deploy (SSH from Actions)

The pipeline builds artifacts and pushes them over SSH (Deployer or rsync + script). More control, more YAML to own — worth it when you need build artifacts identical across environments.

3. The hybrid

CI runs tests; on green, it hits the deploy webhook. You get gated deploys without moving the deployment logic into CI. With Cipi, that's a one-line curl at the end of the workflow.

After the deploy

Migrations & rollback strategy

Put this into practice with Cipi

Cipi is the free, open-source deploy CLI referenced throughout this guide: one command turns a fresh Ubuntu VPS into a hardened production server for Laravel — Nginx, PHP-FPM or Octane, MariaDB or PostgreSQL, queues, scheduler, SSL and zero-downtime Git deploys included.

wget -O - https://cipi.sh/setup.sh | bash

Frequently asked questions

Do I need CI/CD as a solo Laravel developer?

Yes — arguably more than a team does, because nobody reviews your work. A pipeline that runs Pint, Larastan, Pest and composer audit on every push is a tireless second pair of eyes, and webhook-based deploys mean shipping stops being a manual ritual.

How do I get zero-downtime deployments for Laravel?

Use the releases pattern: build the new version in its own directory, run migrations and caches, then atomically swap a symlink and restart queue workers. Tools like Cipi configure this automatically for GitHub and GitLab pushes, so you get zero-downtime deploys without writing deployment scripts.

How long should a Laravel CI pipeline take?

Under five minutes for the common case, or developers start bypassing it. Run Pest in parallel, cache Composer dependencies, and move slow browser tests to a nightly job instead of blocking every PR.

Are database migrations safe with zero-downtime deploys?

Yes, with the expand/contract pattern: make additive changes first, deploy code that works with both schemas, and remove old columns in a later release. Keep destructive changes in their own deploy, and take a pre-deploy snapshot (automatic in Cipi 5) so mistakes are reversible.

Is it safe to deploy on Fridays?

With small diffs, a green pipeline, health checks and one-command rollback — yes. The Friday fear is a symptom of big-batch, manual deployments; fix the process and the day of the week stops mattering.

Keep reading