SYS://VISION.ACTIVE
VIEWPORT.01
LAT 28.0222° N
SIGNAL.NOMINAL
VISION Loading
Back to Blog

Zero-Downtime Deployments for Laravel Applications

Shane Barron

Shane Barron

Laravel Developer & AI Integration Specialist

Users Shouldn't Notice Deployments

Every minute of downtime costs money and trust. Zero-downtime deployment ensures users experience uninterrupted service during updates.

The Release Directory Pattern

/var/www/
├── releases/
│   ├── 20241012-001/
│   ├── 20241012-002/
│   └── 20241012-003/  # Current
├── current -> releases/20241012-003/
├── storage/  # Shared
└── .env      # Shared

Deployment Script

#!/bin/bash
set -e

RELEASE=$(date +%Y%m%d-%H%M%S)
RELEASES_DIR=/var/www/releases
CURRENT_DIR=/var/www/current
SHARED_DIR=/var/www/shared

# Clone repository
git clone --depth 1 $REPO $RELEASES_DIR/$RELEASE

cd $RELEASES_DIR/$RELEASE

# Install dependencies
composer install --no-dev --optimize-autoloader

# Link shared resources
ln -s $SHARED_DIR/.env .env
ln -s $SHARED_DIR/storage storage
rm -rf public/storage
ln -s $SHARED_DIR/storage/app/public public/storage

# Build assets
npm ci && npm run build

# Run migrations
php artisan migrate --force

# Optimize
php artisan config:cache
php artisan route:cache
php artisan view:cache

# Atomic symlink switch
ln -sfn $RELEASES_DIR/$RELEASE $CURRENT_DIR

# Reload PHP-FPM
sudo systemctl reload php8.3-fpm

# Restart queue workers
php artisan queue:restart

# Cleanup old releases (keep 5)
ls -dt $RELEASES_DIR/*/ | tail -n +6 | xargs rm -rf

Using Envoy

// Envoy.blade.php
@servers(['web' => 'deploy@example.com'])

@setup
    $repo = 'git@github.com:user/repo.git';
    $release = date('YmdHis');
    $releases = '/var/www/releases';
    $current = '/var/www/current';
@endsetup

@task('deploy')
    git clone --depth 1 {{ $repo }} {{ $releases }}/{{ $release }}
    cd {{ $releases }}/{{ $release }}
    composer install --no-dev
    php artisan migrate --force
    ln -sfn {{ $releases }}/{{ $release }} {{ $current }}
    sudo systemctl reload php8.3-fpm
@endtask

// Run with: envoy run deploy

Database Migrations

For zero-downtime, migrations must be backward compatible:

  • Add columns as nullable first
  • Deploy code that handles both states
  • Backfill data
  • Add constraints in subsequent deployment

Conclusion

Zero-downtime deployment requires the release directory pattern, atomic symlink switches, and careful migration strategies. The complexity is worth the user experience improvement.

Share this article
Shane Barron

Shane Barron

Strategic Technology Architect with 40 years of experience building production systems. Specializing in Laravel, AI integration, and enterprise architecture.

Need Help With Your Project?

I respond to all inquiries within 24 hours. Let's discuss how I can help build your production-ready system.

Get In Touch