Some quick ’n dirty field notes, adapted from setting up the server that hosts this website.
I recently decided to move clouding providers. The reasons are unimportant.
This blog post is going to go over setting up the Caddy web server, on a Rocky Linux 9 virtual machine.
When I set this up, I used:
I will not be including any of my Terraform .tf
files, or links to my Ansible
roles and playbooks, in this guide.
Instead, I will provide you the commands that you can run manually. This allows you to automate them however you desire.
For this guide, I used Linode. You can use whatever cloud provider (or local hypervisor) you prefer. If you are doing this as a bare-metal install, that is fine too!
There are some important things to note about the Linode-provided virtual machine I set up:
These are important to note, because not every cloud provider provides Rocky Linux virtual machines with these enabled. On DigitalOcean for example, SELinux was enforcing, but firewalld was not enabled.
The rest of this guide assumes that SELinux is enforcing, and that firewalld is enabled as well. There are too many guides out there where the second or third step is disabling SELinux. This kind of stuff does not fly in the real world, so leave SELinux alone, and let it enforce stuff.
Once you have the virtual machine created, it is at this point I recommend creating any required DNS records for pointing your desired domain name, to your virtual machine.
dnf install 'dnf-command(copr)'
dnf copr enable @caddy/caddy
dnf install caddy
Before you start and enable caddy.service
, you should configure it.
The caddy
package puts a bare-bones configuration file at
/etc/caddy/Caddyfile
.
Edit this file to look something like this:
{
debug
}
mysite.com {
encode zstd gzip
root * /srv/mysite.com/
file_server browse {
index index.html
}
log {
output file /var/log/http/mysite.com.access.log
format json
level ERROR
}
}
Remember how I said Caddy has a lot of sane defaults and an simple configuration
file?
This is what I am talking about.
The mysite.com
block has no details about fetching TLS certificates, or
performing HTTP-to-HTTPS redirection.
Caddy handles that out of the box for you.
You can configure how it retrieves TLS certificates, and handles HTTP-to-HTTPS
redirection, but that is an exercise for you, dear reader.
The important thing to note from this Caddyfile sample, is
mysite.com {
root * /srv/mysite.com/
...
and even then, just the root * /srv/mysite.com/
line.
That configuration “directive” sets the directory that content for mysite.com
will be served from.
Next, let’s create that directory.
mkdir -p /srv/mysite.com
Even though SELinux is enabled and set to enforce on the standard Rocky Linux image from Linode, I still had to install an extra package to get the semanage(8) tool.
dnf install policycoreutils-python-utils
Next, we will need to manage the SELinux file context mappings. To do this, we will use semanage(8):
semanage fcontext -a -t httpd_sys_content_t /srv/mysite.com
This command says:
fcontext
(file context)-a
httpd_sys_content_t
type/srv/mysite.com
directory.Lastly, we want to use the restorecon(8) command to restore the SELinux security contexts to our content directory:
restorecon -rv /srv/nesv.ca
Personally, I do this with rsync(1).
First, I had to install the rsync
package on the remote host:
dnf install rsync
For rsync(1) to work, both your local host, and the remote host you are uploading your content to, must have rsync installed.
Then back on your local machine, push the files to the content directory:
rsync -vz public/ user@remotehost:/srv/mysite.com/
Again, as a detail about this Rocky Linux VM provided by Linode, firewalld(1) is enabled as well. If we tried to start Caddy and view our website, we would get an error in the web browser saying something about the connection being interrupted.
Punching a hole in the firewall to allow HTTP and HTTP traffic is simple enough:
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
--permanent
flag persists these changes so we do not have to run these
commands again if the server is ever rebooted;--zone=public
says to issue this command against the public
zone (read up
on firewalld to learn about zones);--add-service=http
and --add-service=https
is the important flag here,
this adds the HTTP and HTTPS services to the firewall rules, effectively
allowing traffic in on ports 80 (HTTP) and 443 (HTTPS).Finally, start and enable the systemd caddy.service
unit:
systemctl enable --now caddy.service
Fantastic! At this point, if you pop open your web browser and go to your domain, you should be greeted by your snazzy website, being hosted by Caddy!
Hopefully, you remembered to create a DNS record to point your domain at the virtual machine’s IP address.