server adminstration

Setting up the Caddy web server

published on
Caddy V2 web server
https://caddyserver.com/v2

Over Black Friday and Cyber Monday I decided to make use of the offers to purchase a few more VPS systems. Over time it is intended that they will replace some of the older VPS systems I currently use.

Whilst setting the first one up I decided to give Caddy a try. It is billed as being a really simple to set up server that provides a number of benefits such as automatic certificates.

I had already got Ubuntu installed on the server. The rest of this post will explain how I got Caddy installed and serving static sites. It can easily be used for dynamic sites using PHP, proxies and load balancers (if required).

Installing Caddy

The first thing I did was to install the server

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc
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

Install and configure the firewall

I like to use UFW so ran the commands below

sudo apt install ufw
sudo ufw default incoming deny
sudo ufw default outgoing allow
sudo ufw allow 80
sudo ufw allow 443

Configure Caddy

I then created a simple Caddyfile by editing the one in /etc/caddy/Caddyfile and added the following lines (make sure to replace anything in italics with your own information if you are using this to set up your own server)

{
        default_sni your_domain_here
        admin off
        email your_email_here
        servers {
                listener_wrappers {
                        http_redirect
                        tls
                }
                protocols h3 h2 h1
        }
}

your_domain_here {
  redir https://www.your_domain_here permanent
}

www.your_domain_here {
  tls {
    protocols tls1.2 tls1.3
      ciphers TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_12>
      }

  encode zstd gzip

  templates

  log {
    output file /var/log/caddy/your_domain_here.access.log {
      roll_size 100mb
      roll_keep 7
      roll_local_time
    }

  # location of the site files
  root * /var/www/your_domain_here

  push

  # set headers

  # cache for four hours
  header ?Cache-Control "max-age=14400"

  @static {
    path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.woff2 *.ttf *.eot
  }

  handle @static {
    # cache for 3 months
    header Cache-Control max-age=7776000
  }

  # put a - in front of a header to strip it
  header {
    -Server
    -X-Powered-By
    X-Real-IP {http.request.remote}
    Host {host}
    Strict-Transport-Security "max-age=31536000; includeSubDomains;"
    X-Content-Type-Options "nosniff"
    X-Frame-Options "DENY"
    X-XSS-Protection "1; mode=block"
    X-Download-Options "noopen"
    X-Permitted-Cross-Domain-Policies "none"
    Referrer-Policy "no-referrer-when-downgrade"
    Content-Security-Policy "upgrade-insecure-requests"
  }

  # serve static files
  file_server
}

Now for the site

Now I created a folder for the site

sudo mkdir /var/www/directory_where_your_site_is

I then copied the necessary files into this directory and ran the following commands

sudo chown -R www-data:www-data /var/www/directory_where_your_site_is

sudo chmod -R 755 /var/www/directory_where_your_site_is

Final thoughts

This is only a fairly basic setup which only serves static content. Using Caddy with a dynamic website is simple enough and doesn't require much more work. 

I've included some settings to enable the experimental HTTP/3 support and a few lines to enable some headers.

The security headers and SSL certificate can be tested at https://securityheaders.com/ and https://www.ssllabs.com/ssltest/index.html respectively.

I've since made some changes and additions to the Caddyfile you see above but this should give you a good start if you wish to install and use the Caddy web server on Ubuntu.