How to Set Up Laravel with Caddy for Performance & HTTPS

How to Set Up Laravel with Caddy for Performance & HTTPS

How to Set Up Laravel with Caddy for Performance & HTTPS

Caddy is a modern web server that makes deploying Laravel 12 projects easier and faster. Unlike Nginx or Apache, Caddy has automatic HTTPS via Let’s Encrypt built-in, simple configuration, and excellent support for HTTP/2 and HTTP/3 (QUIC). In this step-by-step guide, we’ll set up Laravel behind Caddy, configure PHP-FPM, enable caching & compression, and add best practices for production.

1 — Install Caddy & PHP-FPM

On Ubuntu, you can install Caddy from the official repository and PHP-FPM for Laravel.

# Install Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy -y

# Install PHP-FPM 8.3
sudo apt install php8.3-fpm php8.3-cli php8.3-mysql unzip -yCode language: Bash (bash)

This installs both Caddy and PHP-FPM. Caddy handles HTTP/HTTPS while PHP-FPM executes PHP code for Laravel.

2 — Basic Caddyfile for Laravel

Caddy uses a single Caddyfile for configuration. Point the root to Laravel’s public/ folder, enable PHP, and set caching rules.

# /etc/caddy/Caddyfile
your-domain.com {
    root * /var/www/current/public

    # PHP-FPM
    php_fastcgi unix//run/php/php8.3-fpm.sock

    # Clean URLs
    try_files {path} {path}/ /index.php?{query}

    # Static file caching
    @static {
        path_regexp static \.(?:ico|css|js|gif|jpg|jpeg|png|svg|woff2?)$
    }
    header @static Cache-Control max-age=604800

    # Security headers
    header {
        X-Frame-Options SAMEORIGIN
        X-Content-Type-Options nosniff
        Referrer-Policy "strict-origin-when-cross-origin"
    }

    encode gzip zstd
    file_server
}Code language: Nginx (nginx)

This simple Caddyfile enables automatic TLS (no extra steps needed for Let’s Encrypt), serves static assets with caching, enables gzip/zstd compression, and configures PHP-FPM socket handling. Caddy automatically handles certificate renewals.

3 — Zero-Downtime Deploys with Symlinks

Just like Nginx, you can use a current/ symlink for zero-downtime deployments. Upload new code to releases/2025xxxx/ and update the symlink.

# Example deployment script
cd /var/www/releases
mkdir 20250828
unzip /tmp/app.zip -d 20250828
ln -sfn /var/www/releases/20250828 /var/www/current
php /var/www/current/artisan migrate --force
php /var/www/current/artisan config:cache
php /var/www/current/artisan route:cacheCode language: Bash (bash)

The ln -sfn command atomically switches the current symlink to the new release. No downtime—requests are served by the old code until the new one is ready. For a more advanced and automated approach, check out Automating Laravel Deployments with Deployer .

4 — Handling Queues & Scheduler

Shared hosting often won’t give you Supervisor. With Caddy on VPS, you can configure Supervisor for workers and cron for scheduled tasks.

# /etc/supervisor/conf.d/laravel-worker.conf
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/current/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
numprocs=3
redirect_stderr=true
stdout_logfile=/var/www/current/storage/logs/worker.logCode language: Bash (bash)

This keeps 3 queue workers always alive. Pair with Laravel Horizon for UI monitoring. For scheduled tasks, add a cron entry to call artisan schedule:run every minute.

5 — UI: TLS & Header Checker

Caddy’s automatic TLS is great, but you might want a simple Laravel admin page to confirm HTTPS and headers are applied correctly.

// routes/web.php
Route::middleware(['auth','can:viewAdmin'])->get('/caddy-status', function () {
    return view('admin.caddy-status', [
        'scheme' => request()->getScheme(),
        'headers' => [
            'X-Frame-Options' => request()->header('X-Frame-Options'),
            'X-Content-Type-Options' => request()->header('X-Content-Type-Options'),
            'Referrer-Policy' => request()->header('Referrer-Policy'),
            'Content-Encoding' => request()->header('Content-Encoding'),
        ]
    ]);
});Code language: PHP (php)

This route passes key header and scheme info to a Blade view for inspection. You’ll see if the request is truly over HTTPS and whether compression headers (gzip/zstd) are active.

<!-- resources/views/admin/caddy-status.blade.php -->
@extends('layouts.app')
@section('content')
<div class="container">
  <h1 class="mb-4">Caddy Status</h1>
  <p><strong>Scheme:</strong> {{ $scheme }}</p>
  <ul class="list-group">
    @foreach($headers as $key => $value)
      <li class="list-group-item"><strong>{{ $key }}:</strong> {{ $value ?? '—' }}</li>
    @endforeach
  </ul>
</div>
@endsectionCode language: HTML, XML (xml)

This UI confirms your Caddy TLS and security headers are correctly applied, helping you quickly verify production readiness.

Wrapping Up

Caddy is an excellent alternative to Nginx for Laravel deployments: it’s easy to configure, has automatic HTTPS, and supports HTTP/2 and HTTP/3 out of the box. By combining Caddy with PHP-FPM, caching, compression, Supervisor for queues, and good deployment practices, you’ll have a modern, fast, and secure Laravel production setup.

What’s Next

0 Comments

Leave a Comment

Your email address will not be published. Required fields are marked *

Add Comment *

Name *

Email *

Keep Reading...

How to Deploy Laravel 12 on cPanel Hosting
How to Deploy Laravel 12 on cPanel Hosting

How to Deploy Laravel 12 on cPanel Hosting Not every project requires a VPS or cloud infrastructure. Many developers still rely on…

Automating Laravel Deployments with Deployer
Automating Laravel Deployments with Deployer

Automating Laravel Deployments with Deployer Manual deployments invite mistakes: forgotten cache clears, missing assets, downtime during uploads. Deployer is a PHP deployment…

Laravel Deployment Checklist for 2025
Laravel Deployment Checklist for 2025

Laravel Deployment Checklist for 2025 Deploying a Laravel 12 application is more than just copying files to a server. A proper deployment…