Table of Contents
Before You Begin…
This guide assumes you have already setup Alpine Linux (other Linux distro should working just as well) on your desired server of choice. Most commands will need to run via doas (or sudo - but I prefer doas), since you should be logged in as a created user - never root directly.
All the examples in this guide use caddy.ninja for the domains (how meta…). Please remember to change this to your desired URL.
Prep Your Domains
Make sure your DNS records are setup and working as intended with your desired domain. You can check their status with:
dig caddy.ninja
Install Caddy
As your created user, run the following command:
doas apk add caddy
That’s it. Amazing, right?
Configure Caddy
All configuration for our Caddy server takes place under /etc/caddy/Caddyfile. Open this file with your desired terminal editor of choice and following the next steps.
Blocking Spammers & Bots
I highly recommend that you setup some basic 403 routes for spammers, crawlers, and bots. The following assumes you are hosting static files, so adjust accordingly based on your requirements:
(spam_and_bot_block) {
# Everything PHP-related
@php-probes path *.php *.php/* /index.php*
respond @php-probes 403
# WordPress and CMS probes
@cms-probes {
path /wp-* /xmlrpc.php /wp-admin/* /wp-login.php
path /administrator/* /admin/* /user/login /login
path /joomla/* /drupal/* /typo3/*
}
respond @cms-probes 403
# Config / dotfiles / sensitive
@sensitive {
path /.env /.config /.git/* /.svn/* /.hg/* /composer.json /composer.lock
path /config.php /config/* /settings.php /server-status
}
respond @sensitive 403
# Known exploit scanners
@exploit-probes {
path /vendor/* /templates/* /storage/* /cgi-bin/* /owa/*
path /boaform/* /HNAP1* /hudson/* /shell* /phpunit/*
path /_ignition/* /_profiler/* /TP/* /adminer.php
}
respond @exploit-probes 403
# Backup / dump files
@dumpfiles path *.sql *.bak *.zip *.tar *.gz *.tgz
respond @dumpfiles 403
}
Security Headers
Including security headers isn’t required in order for your server to work, but it is still very good practice. The following is based on my own personal preference, so feel free to tweak to your own liking.
We include this section as a snippet, which gives us the ability to easily include it to any other website we decide to host in the future. Future-proofing is always smart.
(security_headers) {
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin"
Content-Security-Policy "default-src 'self';"
Permissions-Policy "microphone=()"
}
}
Error Handling
The next snippet is also optional. This error_handler is where you can tell Caddy what to do for specific HTTP errors. In this example, we will forward all 404 traffic to a designated /404 page for each website using this snippet.
Note: You’ll need to make sure that 404 page exists inside your site directory
(error_handler) {
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404
file_server
}
}
Directory Setup
Now for the main event - configuring your actual web directory! The code itself is pretty straightforward, but we’ll still go over it:
caddy.ninja {
root * /var/www/caddy.ninja
file_server
import spam_and_bot_block
import security_headers
import error_handler
encode gzip
}
www.caddy.ninja {
redir https://caddy.ninja{uri} permanent
}
root * /var/www/caddy.ninja- is the directory containing your website files
file_server- tells Caddy to serve content as - you guessed it - a file server
import spam_and_bot_block- includes our spam and bot block snippet
import security_headers- includes our security header snippet
import error_handler- includes our error handler snippet
encode gzip- generates and serves compressed content files
redirsection- forwards all www requests to non-www
Pretty simple stuff. With that all done, it’s time to start Caddy!
Enable & Run Caddy
Start Caddy and also enable it to run on boot by using the following commands:
doas rc-update add caddy
doas rc-service caddy start
Caddy handles the rest for you. It will automatically request and install a Let’s Encrypt certificate for your domain, and then serve your website over HTTPS.
Now check out your live website! You can do this by visiting your domain in your browser. If everything is setup correctly, you should see your website live and secure with HTTPS!
Happy hosting!