Caddy, sometimes clarified as the Caddy web server, is an open source, a HTTP/2-enabled web server written in Go. It uses the Go standard library for its HTTP functionality.A variety of web site technologies can be served by Caddy, which can also act as a reverse proxy and load balancer.
Capabilities:
- Virtual hosting.
- Native IPv4 and IPv6 support.
- Serve static files.
- Graceful restart/reload
- Reverse proxy.
- Load balancing with health checks.
- FastCGI proxy.
Download Caddy binary file
Execute the following command will download the Caddy binary file and put it in your executable PATH:
curl https://getcaddy.com | bash
Using the command below you can see your binary file path which is by default “/usr/local/bin/caddy”:
which caddy
Preparing the Caddy
As you saw we didn’t install Caddy trough a package so we don’t have any service or configuration files for our web server, In this section we are going to create Caddy configuration files, set their permissions and finally create a service for our web server.
Caddy necessary directories
First of all set the binary file permission to “root” and make it executable with the following commands:
chown root:root /usr/local/bin/caddy
chmod 755 /usr/local/bin/caddy
Execute the following command to permit the Caddy’s binary file to listen on preferred port:
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/caddy
Now we will create the Caddy’s user and group:
groupadd caddy
useradd \
-g caddy \
--home-dir /var/www --no-create-home \
--shell /usr/sbin/nologin \
--system caddy
Create the Caddy main directory and set the proper owner and permission with the commands below:
mkdir /etc/caddy
touch /etc/caddy/Caddyfile
chown -R root:caddy /etc/caddy
chown caddy:caddy /etc/caddy/Caddyfile
chmod 444 /etc/caddy/Caddyfile
Make the SSL directory to store your SSL configurations:
mkdir /etc/ssl/caddy
chown -R caddy:root /etc/ssl/caddy
chmod 770 /etc/ssl/caddy
Create the root directory for Caddy (which you are going to serve your website):
mkdir /var/www
Caddy Service
In this section, we are going to create a “caddy.service” file to get the ability to control our web server.
Create the service file with the command below:
nano /etc/systemd/system/caddy.service
Paste the following script in the file then save and exit:
[Unit]
Description=Caddy HTTP/2 web server
Documentation=https://caddyserver.com/docs
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
#Restart=on-failure
StartLimitInterval=864000
StartLimitBurst=500
; User and group the process will run as.
User=caddy
Group=caddy
; Letsencrypt-issued certificates will be written to this directory.
Environment=CADDYPATH=/etc/ssl/caddy
; Always set "-root" to something safe in case it gets forgotten in the Caddyfile.
ExecStart=/usr/local/bin/caddy -log stdout -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp
ExecReload=/bin/kill -USR1 $MAINPID
; Limit the number of file descriptors; see `man systemd.exec` for more limit settings.
LimitNOFILE=1048576
; Unmodified caddy is not expected to use more than that.
LimitNPROC=64
; Use private /tmp and /var/tmp, which are discarded after caddy stops.
PrivateTmp=true
; Use a minimal /dev
PrivateDevices=true
; Hide /home, /root, and /run/user. Nobody will steal your SSH-keys.
ProtectHome=true
; Make /usr, /boot, /etc and possibly some more folders read-only.
ProtectSystem=full
; … except /etc/ssl/caddy, because we want Letsencrypt-certificates there.
; This merely retains r/w access rights, it does not add any new. Must still be writable on the host!
ReadWriteDirectories=/etc/ssl/caddy
; The following additional security directives only work with systemd v229 or later.
; They further restrict privileges that can be gained by Caddy. Uncomment if you like.
; Note that you may have to add capabilities required by any plugins in use.
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
;NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
Set the owner and permissions for the service file:
chown root:root /etc/systemd/system/caddy.service
chmod 644 /etc/systemd/system/caddy.service
Now run the command below to take effect:
systemctl daemon-reload
You can start, stop and enable the Caddy service with the following commands:
systemctl start caddy
systemctl enable caddy
systemctl status caddy
Installing the PHP and PHP-FPM
In order to serve WordPress, you need to have PHP installed but you need a PHP processor for integrating the PHP with your Caddy web server and that’s why we are going to install PHP-FPM as well.
Execute the following command to install PHP and all of the dependencies that you may need for running WordPress:
apt-get install php php-fpm php-xml php-mbstring php-mcrypt php-gd php-curl
After the installation process is finished, start and enable your PHP-FPM service with the following commands:
systemctl start php7.0-fpm
systemctl enable php7.0-fpm
Next, open the PHP-FPM configuration file with your text editor:
nano /etc/php/7.0/fpm/pool.d/www.conf
Find the following lines:
user = www-data
group = www-data
And change them like below:
user = caddy
group = caddy
Go ahead and find the “listen.owner” lines, Uncomment them and change them to look like below:
listen.owner = caddy
listen.group = caddy
listen.mode = 0660
Find the line that starts with “listen” and changes the value like below:
listen = 127.0.0.1:9000
Save and Exit.
Restart the PHP-FPM service to take effect:
systemctl restart php7.0-fpm
Open your Caddyfile with a text editor:
nano /etc/caddy/Caddyfile
Paste the following configuration in it:
YOUR_DOMAIN_OR_IP_ADDRESS:80 {
tls admin@YOUR_DOMAIN
root /var/www/
gzip
fastcgi / 127.0.0.1:9000 php
rewrite {
if {path} not_match ^\/wp-admin
to {path} {path}/ /index.php?_url={uri}
}
}
Now you can test if your PHP and web server is working together properly.
Create a file named “info.php” in your web server’s root directory:
nano /var/www/info.php
paste the following code into it then save and exit:
<?php
phpinfo();
?>
Now you can open your browser and see your Domain or your public IP address (e.g. http://IP_DOMAIN/info.php)