Setting up a Web Server on Raspberry Pi with Caddy 2

Goal:

Our goal is to set up a Raspberry Pi web server that we can use to put simple pages or applications on the internet.

I will go over how I set up my personal web page, but Caddy 2 is highly adaptable to your use.

Materials:

  1. Raspberry Pi that can connect to the internet (using built-in Wi-Fi or a dongle)
  2. Optional: a domain name

Software Used:

  1. Caddy 2
  2. PuTTY (or another SSH client). PuTTY

Step 1: Install Go and build Caddy 2 from source

Caddy 2 is in beta, but it is a fully functional open source web server with automatic HTTPS.

To get Caddy, we need to install Go first.

                
                    $ wget https://dl.google.com/go/go1.13.5.linux-armv6l.tar.gz
                    $ sudo tar -C /usr/local -xzf go1.13.5.linux-armv6l.tar.gz
                    $ rm go1.13.5.linux-armv6l.tar.gz
                
            

We need to update our PATH to point to where Go is and where we will be working when we build Caddy.

                
                    $ nano ~/.profile
                
            

Scroll to the bottom and add these two lines. You can substitute the GOPATH to any directory where you want to work in.

                
                    PATH=$PATH:/usr/local/go/bin
                    GOPATH=$HOME/web
                
            

Now go to this GOPATH directory and clone the Caddy repository.

                
                    $ git clone -b v2 "https://github.com/caddyserver/caddy.git caddy_git"
                    $ cd caddy_git/cmd/caddy/
                    $ go build
                
            

This builds the caddy executable. Move this to where you want it. I put it on the same level as my website's repository, so my files look like this:

                
                    ~
                    |__ go
                    |   |__ bin
                    |   |__ pkg
                    |__ web
                        |__ <my website's repository>
                        |__ caddy
                        |__ caddy_git
                
            

Step 2: Make a basic config file for Caddy

Now that Caddy is ready for use, we need to write a config file. Caddy is configured while running by sending a POST request to a REST API. These updates can be done on the fly, which makes developing with Caddy very nice as our updates are visible right away.

Caddy 2's config files are written in plain JSON. The excellent documentation has the complete config spec and some examples.

Make a file called caddy.json:

                
                    {
                        "apps": {
                            "http": {
                                "servers:" {
                                    "<any name here> e.g. myserver": {
                                        "listen": ["<your pi's local IP>:2080"],
                                        "routes": [{
                                            "handle": [{
                                                "handler": "file_server",
                                                "root": "<path to a folder relative to your caddy executable>",
                                                "index_names": ["<a file to display> e.g. index.php"],
                                                "browse": {}
                                            }]
                                        }]
                                    }
                                }
                            }
                        }
                    }
                
            

This config file makes a file server served on port 2080, that displays the file specified.

To use this configuration:

                
                    $ ./caddy start
                    $ curl -X POST "http://localhost:2019/load" -H "Content-Type: application/json" -d @caddy.json
                
            

Now navigate to the IP of the Raspberry Pi on your local network, using the port 2080, e.g. "10.0.0.208:2080". You should see your page displayed.

To stop Caddy:

                
                    $ ./caddy stop
                
            

Step 3: adding a port forward to the Raspberry Pi

Adding a port forward to your Raspberry Pi means the ports specified will be available externally, so you won't have to be on the local network to make changes and to see the server. Adding a port forward creates a security risk, so make sure to take that into consideration and change the default password on the Pi.

Port forwarding is going to vary by ISP, but this is what I was able to do on xfinity xFi app:

Adding ports.

To find Add Port Forward navigate through Network and Advanced Settings to Port Forwarding.

To get the above example working, add port 2080.

The HTTP/HTTPS ports 80/443 can be forwarded too.

Step 4: Use your domain

To have our web server served over the internet with a custom domain, we only need to make a few changes to the caddy.json file made earlier.

                
                    {
                        "apps": {
                            "http": {
                                "servers:" {
                                    "<any name here> e.g. myserver": {
                                        "listen": [":443"],
                                        "routes": [{
                                            "match": [{
                                                "host": ["<your domain>", "www.<your domain>"]
                                            }],
                                            "handle": [{
                                                "handler": "file_server",
                                                "root": "<path to a folder relative to your caddy executable>",
                                                "index_names": ["<a file to display> e.g. index.php"],
                                                "browse": {}
                                            }]
                                        }]
                                    }
                                }
                            }
                        }
                    }
                
            

If your DNS are pointed to the Raspberry Pi, Caddy will serve the web server on the internet with HTTPS.