How to Host a Website with the Caddy Web Server on Linux

Caddy is a new web server that’s extremely easy to configure and use. It provides HTTP/2 support, built-in integration with Let’s Encrypt and an intuitive configuration syntax. In addition, you can add various plugins for additional features, such as ratelimiting, blocking IPs, and minifying assets.

In this article, we’re going to install Caddy on a Linux system and configure it to serve a website. As with most of our guides here, these instructions should work on most popular distributions such as Debian, Ubuntu and CentOS.

Update (25th September 2017): At the time when this article was written, Caddy was free to use for any purpose. However, due to a recent change, you must buy a commercial license to use the official Caddy binaries for business use. In this article, we will show how to download the free version, that can be used for personal and academic use.

Keep in mind that Caddy itself is still open-source, so you can compile Caddy on your own for business use without having to pay. The restriction only applies to the pre-built binaries from caddyserver.com.

Installing the Caddy binary

The Caddy project provides a shell script so that you can easily install Caddy on your system. First, you should download the script and make it executable.

wget https://getcaddy.com -O getcaddy
chmod +x getcaddy

Then, you simply need to execute the script like so:

sudo ./getcaddy personal

If you want to get a version of Caddy with plugins, head over to the download page and note down the plugins you want. Say, for example, you want to install the http.ipfilter and http.ratelimit plugins. Then, run the script like so:

sudo ./getcaddy personal http.ipfilter,http.ratelimit

Now, the script will download the binary and install it in /usr/local/bin/caddy. Now, if you type in caddy from the command line, Caddy will start serving files in the current directory on port 2015. You can open http://<your_server_ip>:2015/ in a browser to verify this.

As we’ve seen, getting started with Caddy is easy. However, to use it as a general purpose web server, we need to configure it to start automatically when the server boots up. The installation script doesn’t set this up, so we’ll manually do it.

Setting up user accounts and directories

The first step is to create a restricted user account for Caddy to run in. In our example, we’ll create an user named caddy with the home directory set to /opt/caddy using:

sudo useradd -rmd /opt/caddy caddy

The /opt/caddy directory will store various server related files, such as configuration files and website data. In addition, we’re going to create:

/opt/caddy/store to store SSL certificates and other persisted state files.

/opt/caddy/logs to store server logs.

In order to create these directories, run:

sudo mkdir /opt/caddy/store /opt/caddy/logs

You should also transfer the ownership of everything inside /opt/caddy to the caddy user so that the server can read and modify all files inside it with:

sudo chown -R caddy: /opt/caddy

Auto-starting Caddy

Now that we’ve the users and directories set up, we have to set up Caddy to run automatically when the server starts. However, first you need to find out the init system that’s in use. To do this run (source):

This will serve the contents of /opt/caddy/web/default over port 80. The request log for this website will be stored in /opt/caddy/logs/default.log. Moreover, because we’ve used the gzip directive, text-based files will be compressed with gzip and served, thus saving bandwidth.

Of course, since the webserver isn’t running yet, you have to start it up. On a distribution with systemd, run:

sudo systemctl start caddy.service

On sysvinit/upstart based distros, run:

sudo service caddy start

If you want to check if things are working as intended, add a file named index.html to the /opt/caddy/web/default directory. Now, if you open your website in a browser, you’ll see that the index.html file is being served.

Serving multiple websites

If you want to host multiple websites, that’s possible too! You simply need to add multiple blocks like this:

When a visitor visits your server with example.com, Caddy will serve them files from /opt/caddy/web/example. Similarly, when they access your website with otherwebsite.com, Caddy will serve them files from /opt/caddy/web/otherwebsite. Finally, the last block with http:// acts as a “fallback” — if a visitor visits it using any other hostname (such as directly accessing with the IP) Caddy will serve them files from /opt/caddy/web/default. You can remove this block if you don’t want the “fallback” functionality.

When you change the configuration file, you should restart the server so that the changes come into effect. On a systemd distribution, type in:

sudo systemctl restart caddy.service

For sysvinit/upstart-based distributions, the command is different:

sudo service caddy restart

HTTPS configuration

One of the best features of Caddy is its integration with Let’s Encrypt, an automated certification authority. Thus, you can enable HTTPS for your websites very easily.

Before you begin, you need to have a domain name. This is because Let’s Encrypt can issue SSL certificates for domains only.

In the example above, we’ve added a tls directive with an email address. Let’s Encrypt’s servers will send you expiration notices to this address. Once you restart your server, Caddy will automatically contact the Let’s Encrypt servers, and deploy HTTPS on your site. There’s no need for a HTTP block — HTTP requests are redirected to HTTPS automatically.

Serving some real content

With our current setup, you can serve static files just fine. However, that isn’t very useful. Let’s look at some small examples of serving some real content — and that’s where Caddy shines!

Serving markdown files

Markdown is a lightweight markup language that translates to HTML. With Caddy, you can serve markdown files with a one-liner. Modify the block in your Caddyfile like so:

http:// {
# other directives
markdown /
}

Now, Caddy will serve any file with a .md, .mdown or a .markdown extension as a regular web page. What’s more, you can place a file named index.md in a directory — it automatically becomes the default document for that directory.

PHP files

First, you need to install PHP-FPM on your server — it’s available as a package on most distributions. Then, you need to configure the PHP-FPM daemon to run as the user caddy, and to listen on 127.0.0.1:9000.

The exact file you have to edit varies among distributions. On Debian and Ubuntu, it’s usally a file named /etc/php/<version_number>/fpm/pool.d/www.conf. On CentOS/RHEL, you have to edit /etc/php-fpm.d/www.conf. After opening the file, you need to change the values like so:

user = caddy
group = caddy
listen = 127.0.0.1:9000

Now, in your Caddyfile, put in the following directive:

http:// {
# other directives
fastcgi / localhost:9000 php
}

This will pass any files with the .php extension to PHP-FPM. You can easily verify if it’s working by pointing your browser to a PHP file.

Conclusion

As we’ve seen, Caddy makes it extremely easy to configure and host websites quickly. If you would like to know more, the documentation is a good place to start.

Would you give Caddy a try for your next website? What was your experience like? Did you run into any problems? Let us know in the comments below.