Add tutorial about setting up caddy server

This commit is contained in:
anjomro 2023-09-29 14:49:34 +02:00
parent 487a2015ef
commit ea7b50d95c

View file

@ -0,0 +1,398 @@
---
title: Setup of Caddy Server - The easiest way to provide secure HTTPS connections
description: Caddy is a web server that is very easy to setup and maintain. It uses Let's Encrypt certificates almost without configuration!
level: [ beginner ]
updated_at: 2023-09-29
slug: setup-caddy
author_name: Anton Mrosek
author_url: https://github.com/anjomro/
author_image: https://avatars.githubusercontent.com/u/17234179?v=4
author_bio:
tags: [ shell, ssh, linux, caddy, webserver, https, tls, reverse-proxy]
netcup_product_url: https://www.netcup.de/bestellen/produkt.php?produkt=2948
language: en
available_languages: [ de, en ]
---
# Introduction
This tutorial explains how to setup the caddy web server. Additionally, it shows how to serve static files using caddy
as well as how to run a reverse proxy, that e.g. exposes services running on docker to the outside world.
Caddy is easy to use and configure, due to its configuration file format. A simple configration file for a reverse proxy
featuring automatic HTTPS can look like this:
```
my-cool-domain.de {
reverse_proxy localhost:8080
}
```
We'll go into detail about the caddy server configuration later on.
<details>
<summary>An equivalent nginx server config might look like this and require additional tools like certbot:</summary>
```
server {
listen 80;
server_name my-cool-domain.de www.my-cool-domain.de;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ /.well-known/acme-challenge {
allow all;
}
location = /.well-known/acme-challenge/ {
return 404;
}
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/my-cool-domain.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-cool-domain.de/privkey.pem;
}
```
</details>
<details>
<summary>An equivalent apache2 server config might look like this and would require a tool like certbot as well:</summary>
```
<VirtualHost *:80>
ServerName my-cool-domain.de
ServerAlias www.my-cool-domain.de
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
DocumentRoot /var/www/html
<Directory /var/www/html>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
Alias /.well-known/acme-challenge/ /var/www/html/.well-known/acme-challenge/
</VirtualHost>
```
</details>
As you can see the caddy configuration is much simpler and easier to understand. Caddy also takes care of obtaining and
using the Let's Encrypt certificate without any configuration!
So let's get started on how to setup caddy on your own server.
# Requirements
For following this tutorial you need the following:
- A server (e.g. VPS) running a recent Version of Ubuntu and access over SSH
- The server needs a public ipv4 or ipv6 address. Netcup VPS / RS server always have ipv4 and ipv6 addresses.
- The tutorial might be applicable to other linux distributions, only the actual installation of caddy might differ.
- A domain name or a subdomain where you have control over the DNS settings
- Optional: If you want to create a reverse proxy using caddy you need a service running on your server that you want to
expose to
the outside world.
For this tutorial we will use the domain `my-cool-domain.de` as an example. You can replace it with your own domain name
or subdomain.
# Step 1 - Setting up the DNS records
For using your domain with your server it is necessary to set up the DNS records to point to teh public ipv4 and/or ipv6
address of your server. If both are set the client will choose whether to connect via ipv4 or ipv6.
## Step 1.1 - Getting the IP Adresses of your server
First we need to get the public ipv4 and ipv6 addresses of your server. This can be done using the following commands
that you can run on your server:
```bash
echo -n -e "\n\nipv4 address: " && curl -4 ifconfig.co
echo -n -e "\nipv6 address: " && curl -6 ifconfig.co
```
Note down your servers ipv4 and ipv6 address. We will need them in the next step.
If you're seeing something like: `ipv6 address: curl: (7) Couldn't connect to server` then your server might not have
an ipv6 address. In that case you can use the ipv4 address only, it will work just fine.
## Step 1.2 - Setting up the DNS records
The DNS records can be changed your DNS provider. If you haven't changed the default settings this most likely is the
place where you bought your domain.
If you purchased your domain at Netcup you can change the DNS records in the Customer Control Panel. There you need to
select `Domains` > `my-cool-domain.de` > `DNS`.
Then add the following entries to the DNS records:
| Type | Host | Value |
|------|------|-----------------------------|
| A | @ | ipv4 address of your server |
| AAAA | @ | ipv6 address of your server |
If you don't have ipv4 or ipv6 you can omit the corresponding entry.
## Step 1.3 - Checking the DNS records
It can take up to 24 hours for the DNS records to be updated. However, it usually takes only a few minutes. You can
check if the DNS records are updated using the following command:
```bash
dig +short my-cool-domain.de
```
If you see the ipv4 and/or ipv6 address of your server the DNS records are updated and you can continue with the next
step.
# Step 2 - Installing caddy
## Step 2.1 - Adding the caddy repository
Caddy is not available in the default Ubuntu repositories. Therefore we need to add the caddy repository first. This can
be done using the following commands:
- Download and install the repository signing key, so that the packages can be verified:
- Enter your password when prompted (applies also to the following commands)
```bash
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /usr/share/keyrings/caddy.asc
```
- Setup the repository:
```bash
echo "deb [signed-by=/usr/share/keyrings/caddy.asc] https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main" | sudo tee -a /etc/apt/sources.list.d/caddy-stable.list
```
- Update the package cache, so that the packages from the new repository are available:
```bash
sudo apt update
```
## Step 2.2 - Installing caddy
Now that the repository is added we can install caddy using the following command:
```bash
sudo apt install caddy
```
Congratulations! You have successfully installed caddy on your server!
# Step 3 - Configuring caddy
The configuration file of caddy, the `Caddyfile`, is located at `/etc/caddy/Caddyfile`.
## Step 3.1 - Checking the default configuration and emptying the `Caddyfile`
You can have a look at it using the following command:
```bash
sudo cat /etc/caddy/Caddyfile
```
<details>
<summary>Your Caddyfile should look similar to this:</summary>
```
# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.
:80 {
# Set this path to your site's directory.
root * /usr/share/caddy
# Enable the static file server.
file_server
# Another common task is to set up a reverse proxy:
# reverse_proxy localhost:8080
# Or serve a PHP site through php-fpm:
# php_fastcgi localhost:9000
}
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile
```
</details>
For configuring caddy it will be the easiest to start with a blank `Caddyfile` and add the configuration step by step.
To delete the default contents of the `Caddyfile` you can use the following command:
```bash
sudo truncate -s 0 /etc/caddy/Caddyfile
```
You can verify that the `Caddyfile` is indeed empty by checking the contents again, if you like:
```bash
sudo cat /etc/caddy/Caddyfile
```
## Step 3.2 - Adding the first configuration
Now we can add our first configuration to the `Caddyfile`. We will start with a simple configuration that serves the
static html page that came with the caddy installation.
To open and edit the `Caddyfile` you can use the following command:
```bash
sudo nano /etc/caddy/Caddyfile
```
To save the file you can press `CTRL + S` and to exit the editor you can press `CTRL + X`. Make sure to always save your
changes.
For the following steps only parts of the `Caddyfile` will be shown. You can simply copy these parts and paste them
underneith the existing content of the `Caddyfile`. However you must make sure that only one entry is present for one
name (e.g. `my-cool-domain.de`), that is important for domains as well as subdomains. If you have multiple entries for a
name caddy will fail to start since it won't know which entry to use for the name.
### Step 3.2.1 - Your first entry: Serving static html files
The first entry will serve static html files. For this we will use the `file_server` directive. The `file_server` will
serve files from the directory specified in the `root` directive. The `root` directive must be specified before the
`file_server` directive.
#### Note: If you've set up a firewall you need to allow incoming connections on port 80 and 443 for caddy to work.
For example, you can add the following lines to the `Caddyfile`. Remember to replace `my-cool-domain.de` with your own
domain or subdomain where you configured the DNS records in step 1.2.
```
my-cool-domain.de {
root * /usr/share/caddy
file_server
}
```
To activate your changes you need to let caddy reload the configuration using the following command:
```bash
sudo systemctl reload caddy
```
To see if caddy is running and for seeing some debugging output, e.g. if there is an error in your `Caddyfile` you can use the following command:
```bash
sudo systemctl status caddy
```
Now you can open your domain in your browser and you should see the default caddy page at your domain/subdomain.
Just enter https://my-cool-domain.de in your browser and you should see the default caddy page.
If that doesn't work right away wait a minute, since caddy needs to request and setup the tls certificate.
If you pay close attention and depending on the browser you'll see a padlock icon in the address bar, indicating that
the connection is encrypted using https. In the background caddy has requested a tls certificate from Let's Encrypt
and configured it for your domain.
### Step 3.2.2 - Optional: Caddy as a reverse proxy
If you have a service running on your server that you want to expose to the outside world you can use caddy as a reverse
proxy.
For this purpose you can use the `reverse_proxy` directive. The `reverse_proxy` directive will forward all requests to
the specified address.
If you have a webservice running on port 8080 on your server you can use the following configuration to expose it to the
outside world:
```
my-cool-domain.de {
reverse_proxy localhost:8080
}
```
Make sure that you don't have any other entries for `my-cool-domain.de` in your `Caddyfile` or caddy will fail to start.
To activate your changes you need to let caddy reload the configuration using the following command:
```bash
sudo systemctl reload caddy
```
# Conclusion
We've now seen how to set up the server with two basic configurations. However, there are many more options available
with caddy, also the shown configurations can be extended.
These informations are available in the [caddy documentation](https://caddyserver.com/docs/caddyfile).
You can try out other directives you can find there in the same way we've done it in this tutorial. Just add them to the `Caddyfile` and reload caddy using `sudo systemctl reload caddy`.
I find working with caddy and the `Caddyfile` very easy and intuitive. I hope you do too!
# Licence
[MIT](https://github.com/netcup-community/community-tutorials/blob/main/LICENSE)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Contributor's Certificate of Origin
By making a contribution to this project, I certify that:
1) The contribution was created in whole or in part by me and I have the right to submit it under the licence indicated
in the file; or
2) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate
licence and I have the right under that licence to submit that work with modifications, whether created in whole or
in part by me, under the same licence (unless I am permitted to submit under a different licence), as indicated in
the file; or
3) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not
modified it.
4) I understand and agree that this project and the contribution are public and that a record of the contribution (
including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be
redistributed consistent with this project or the licence(s) involved.