back
written on 2 January 2024
How to Set Up A Caddy Web Server
rcg   ·   2 January, 2024

Caddy is a powerful, extensible platform to serve your sites, services, and apps. It is written in Go.
In addition to being a web server, I've used Caddy with a reverse proxy to Node to perform other web services.
Prior To Installing Caddy
  1. log into the remote machine
  2. sudo apt update
  3. sudo apt dist-upgrade
  4. sudo apt autoclean
  5. sudo apt autoremove
  6. make sure your A and AAAA DNS records point to this machine
Install Caddy on Ubuntu
Note: for other operating systems, this page shows how to download and install Caddy.
  1. sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
  2. curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
  3. curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
  4. sudo apt update
  5. sudo apt install caddy
  6. sudo setcap CAP_NET_BIND_SERVICE=+eip $(which caddy)
Run Caddy (even on reboot)
  1. whereis caddy
  2. sudo mv caddy /usr/bin/
  3. caddy version # tests that it worked

Caddy may have created a user and group, but just in case:
  1. sudo groupadd --system caddy
  2. sudo useradd --system \
                 --gid caddy \
                 --create-home \
                 --home-dir /var/lib/caddy \
                 --shell /usr/sbin/nologin \
                 --comment "Caddy web server" \
                 caddy
            
Now create the webroot location and some web content:
  1. sudo mkdir /var/www
  2. sudo chown ubuntu:caddy /var/www
  3. sudo mkdir /var/www/public
  4. sudo chown ubuntu:caddy /var/www/public
  5. create some HTML to show:
    emacs /var/www/public/index.html
    <!DOCTYPE html>
    <html>
    <head><title>Hello from Caddy!</title></head>
    <body>
      <h1 style="font-family:arial; text-align:center;">
        This page is being served via Caddy
      </h1>
    </body>
    </html>
    

Download the systemd unit file from the Caddy GitHub and run systemctl:
  1. sudo sh -c 'curl https://raw.githubusercontent.com/caddyserver/dist/master/init/caddy.service > /etc/systemd/system/caddy.service'
  2. more /etc/systemd/system/caddy.service # make sure ExecStart and ExecReload are correct
  3. sudo systemctl daemon-reload # reload systemctl to detect the caddy service
  4. sudo systemctl enable --now caddy # keep caddy running on a reboot
  5. sudo systemctl status caddy # verify running
Set up the Caddyfile Config
Note that the filename is uppercase.
  1. cd /etc/caddy
  2. sudo mv Caddyfile CaddyfileOrig
  3. sudo emacs Caddyfile
    http:// { root * /var/www/public encode gzip file_server }

  4. sudo caddy fmt --overwrite Caddyfile
  5. sudo caddy validate
    I've noticed that logs stop on a simple reload, so do a force stop/start of caddy:
  6. sudo systemctl stop caddy
  7. sudo systemctl restart caddy
  8. sudo systemctl status caddy

You can visit your server’s IP in a web browser to see the page!
A More Detailed Caddyfile And Logging
To enable logging, set up the Caddyfile and create directories. Caddy does some nice things to format logs and keep them from filling up your file system.

Replace "exampleCom" with your domain name.

  1. sudo mkdir /var/www/logs
  2. sudo chown caddy /var/www/logs
  3. sudo mkdir /var/www/logs/caddyLogs
  4. sudo chown caddy /var/www/logs/caddyLogs
  5. sudo mkdir /var/www/logs/exampleComLogs
  6. sudo chown caddy /var/www/logs/exampleComLogs
  7. sudo emacs /etc/caddy/Caddyfile
    # @fileoverview: Caddyfile see also https://caddyserver.com/docs/caddyfile #global { # enable caddy server logs -- sudo chown caddy this log log { output file /var/www/logs/caddyLogs } } #:80 { #example.com { http:// { root * /var/www/public # set the web root path to your site's directory file_server # enable the static file server. encode gzip # enable compression # enable the site-specific logs -- sudo chown caddy this log log { output file /var/www/logs/exampleComLogs } handle_errors { # make all errors (404, etc) go to error.html rewrite * /error.html file_server } # reverse_proxy localhost:3334 # set up a reverse proxy # php_fastcgi localhost:9000 # serve a PHP site through php-fpm } # example of re-direction but cloudflare and caddy handle it #www.example.com { # redir https://example.com #}

  8. sudo caddy fmt --overwrite Caddyfile
  9. sudo caddy validate
    I've noticed that logs stop on a simple reload, so do a force stop/start of caddy:
  10. sudo systemctl stop caddy
  11. sudo systemctl restart caddy
  12. sudo systemctl status caddy
  13. create /var/www/error.html

Of Note:
Caddy Paths
Caddy Service Commands
Uninstalling Caddy
  1. sudo systemctl stop caddy
  2. sudo systemctl disable --now caddy
  3. sudo systemctl daemon-reload
  4. sudo systemctl reset-failed
  5. systemctl cat service
  6. sudo rm /etc/apt/sources.list.d/caddy-stable.list
  7. sudo apt remove caddy
  8. sudo groupdel --system caddy
  9. sudo killall -u caddy
  10. sudo userdel -rf caddy
References
  1. Welcome — Caddy Documentation
  2. Install — Caddy Documentation
  3. Getting Started — Caddy Documentation
  4. Keep Caddy Running — Caddy Documentation
  5. Caddyfile Tutorial — Caddy Documentation
  6. How To Host a Website with Caddy on Ubuntu 22.04 | DigitalOcean
  7. How to solve status 403 in Caddy version 2 - Help
  8. JSON Config Structure - Caddy Documentation
  9. Caddy Wiki