Using the Caddy web server with Laravel is really easy and straightforward.

I find it way easier to setup and manage than Nginx and CertBot). I initially installed Nginx using this bgui and this tutorial, but I didn't like it as the configuration was too complex and cumbersome.

Let's show how easy it can be to get it up and running with Caddy instead, so that we don't have to care about the renewal of certificates or complex configuration files.

So, I decided to replace Nginx with Caddy.

Just for the reference, we're running Ubuntu here. If you are using another distribution, you might want to check the Caddy installation guide for the proper install procedure.

I first stopped and disabled Nginx and certbot:

$ sudo systemctl stop nginx
$ sudo systemctl stop certbot
$ sudo systemctl stop certbot.timer
$ sudo systemctl disable nginx
$ sudo systemctl disable certbot
$ sudo systemctl disable certbot.timer

Let's first install Caddy itself as described in the documentation:

$ 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-stable-archive-keyring.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

Next up is to edit the /etc/caddy/Caddyfile, adding the mysite.com website:

mysite.com, www.mysite.com {
        root * /var/www/mysite.com/public
        encode zstd gzip
        file_server
        php_fastcgi unix//var/run/php/php8.1-fpm.sock
}

As you can see, the config is really easy. Let's go over this line by line:

This first line indicates which hostnames we want to serve. We're serving both the domain with and without the www. prefix.

The root directive tells Caddy where the files for that site can be found. It's important to point to the public folder here.

The encode directive is used to compress the responses. In this case, we're enabling zstd and gzip compression.

The file_server directive sets up a static file server.

The php_fastcgi directive is a so-called "opiniated directive" that directs to a php-fpm FastCGI server. It's basically a shortcut for the following configuration:

route {
    # Add trailing slash for directory requests
    @canonicalPath {
        file {path}/index.php
        not path */
    }
    redir @canonicalPath {path}/ 308

    # If the requested file does not exist, try index files
    @indexFiles file {
        try_files {path} {path}/index.php index.php
        split_path .php
    }
    rewrite @indexFiles {http.matchers.file.relative}

    # Proxy PHP files to the FastCGI responder
    @phpFiles path *.php
    reverse_proxy @phpFiles <php-fpm_gateway> {
        transport fastcgi {
            split .php
        }
    }
}

Once that is done, all that is left is to restart Caddy:

$ sudo systemctl restart caddy

You can check if it's up and running like using the status command:

$ sudo systemctl status caddy

That's it, it's as easy as that. All the rest is done automatically. It will automatically generate the Let's Encrypt SSL certificate and serve the site.

You can automate it slightly more by using snippets as explained here.