In this article, we will cover the steps to install Caddy Web server on Ubuntu systems and how to secure it with Let’s Encrypt SSL certificates. Caddy is an open-source, production-ready that is build to be fast, easy to use, and makes you more productive. Caddy is available for Windows, Mac, Linux, BSD, Solaris, and Android.
Features of Caddy Web Server
- Easy configuration and management with the Caddyfile
- It is secure – Has automatic HTTPS on by default (via Let’s Encrypt)
- Cady uses HTTP/2 by default
- Support multiple sites hosting by using Virtual hosting
- TLS session ticket key rotation for more secure connections
- Its functionalities can be extended with plugins
- Works for both Dynamic and Static sites
- Caddy has zero-downtime reloads
- Caddy is written in Go and has no external dependencies – The binary is entirely self-contained and runs on every platform, including containers.
Install Caddy web server on Ubuntu
Before we do the installation let’s make sure our system is updated.
sudo apt update && sudo apt upgrade -y
If a reboot is required perform it.
[ -e /var/run/reboot-required ] && sudo reboot
Next install dependency packages.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
Import repository GPG key:
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
Add Caddy repository in the system.
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
Install Caddy web server package.
sudo apt update && sudo apt install caddy
The service is automatically started after the installation:
$ systemctl status caddy
systemctl status caddy
● caddy.service - Caddy
Loaded: loaded (/usr/lib/systemd/system/caddy.service; enabled; preset: enabled)
Active: active (running) since Fri 2024-08-02 15:57:49 UTC; 8s ago
Docs: https://caddyserver.com/docs/
Main PID: 58959 (caddy)
Tasks: 7 (limit: 4658)
Memory: 11.2M (peak: 11.7M)
CPU: 56ms
CGroup: /system.slice/caddy.service
└─58959 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"info","ts":1722614269.4687006,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//127.0.0.1:2019",">
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"warn","ts":1722614269.468792,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server">
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"info","ts":1722614269.4689922,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"info","ts":1722614269.4691348,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"info","ts":1722614269.469223,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0008f8600"}
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"info","ts":1722614269.4694684,"msg":"[INFO][FileStorage:/var/lib/caddy/.local/share/caddy] Lock for 'storage_clean' is stale (created: 2024-08-02 15:57:14.3594>
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"info","ts":1722614269.4695828,"msg":"serving initial configuration"}
Aug 02 15:57:49 ubuntu-cloudspinx-com systemd[1]: Started caddy.service - Caddy.
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"info","ts":1722614269.4713044,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/var/lib/caddy/.local/share/caddy"}
Aug 02 15:57:49 ubuntu-cloudspinx-com caddy[58959]: {"level":"info","ts":1722614269.4714336,"logger":"tls","msg":"finished cleaning storage units"}
Using Caddy Web Server – Host WordPress Website
We will consider an example to host a WordPress powered website using Caddy web server on Ubuntu Linux system.
To run WordPress website, you need PHP, Web server, and Database server:
sudo apt -y install vim wget php-fpm php-mysql php-curl php-gd php-mbstring php-common php-xml php-xmlrpc
Install and Configure MariaDB Database server
Install and configure MariaDB database server using:
sudo apt install mariadb-server
Once done, login as root user and create a database for WordPress
$ sudo mysql
CREATE DATABASE wp_site;
GRANT ALL PRIVILEGES ON wp_site.* to 'wp_user'@'localhost' IDENTIFIED BY 'StrongPassword';
FLUSH PRIVILEGES;
EXIT
Download WordPress and Install
Now download WordPress and untar the archive:
wget http://wordpress.org/latest.tar.gz tar xvf latest.tar.gz
tar xvf latest.tar.gz
This will extract all content of the tarball to a folder named wordpress on your working directory.
Move the wordpress
folder to /var/www
directory
sudo mv wordpress/ /var/www/
Change ownership permissions to userwww-data
and group.
sudo chown -R www-data:www-data /var/www/wordpress
Configure WordPress database connection
sudo mv /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php
Edit the file to configure:
$ sudo vim /var/www/wordpress/wp-config.php
// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wp_site' );
/** Database username */
define( 'DB_USER', 'wp_user' );
/** Database password */
define( 'DB_PASSWORD', 'StrongPassword' );
/** Database hostname */
define( 'DB_HOST', 'localhost' );
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
Configuring Caddy to Serve the WordPress Site
We have WordPress installation ready, we now need to configure Caddy Web server to serve our WordPress website. Start by creating a Caddy configuration file on /etc/caddy/Caddyfile
sudo vim /etc/caddy/Caddyfile
Add the contents below and edit to suit your application.
your.domain {
# good practice to signal on behalf of who
# are the certs getting issue
tls [email protected]
# logs are optional
log {
output file /var/log/caddy/your.domain
format console
}
root * /var/www/wordpress
encode gzip
file_server
php_fastcgi unix//run/php/php-fpm.sock
@disallowed {
path /xmlrpc.php
path *.sql
path /wp-content/uploads/*.php
}
rewrite @disallowed '/index.php'
}
Replace your.domain
with your actual domain for WordPress website and [email protected]
with an actual email address used to request Let’s Encrypt certificate. We’re using php-fpm
via fastcgi to support php.
Validate Caddy confguration:
sudo caddy validate --config /etc/caddy/Caddyfile
Restart Caddy server after making the change:
sudo systemctl restart caddy.service
If the start was successful, you should get a successful message:
$ systemctl status caddy
● caddy.service - Caddy
Loaded: loaded (/lib/systemd/system/caddy.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2024-08-02 15:57:49 UTC; 6min ago
Docs: https://caddyserver.com/docs/
Main PID: 33989 (caddy)
Tasks: 7 (limit: 4523)
Memory: 13.9M
CPU: 185ms
CGroup: /system.slice/caddy.service
└─33989 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
Aug 02 10:05:40 jammy caddy[33989]: {"level":"info","ts":1694426740.073787,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["wp.computingforgeeks.net"],"ca">
Aug 02 10:05:40 jammy caddy[33989]: {"level":"info","ts":1694426740.4404023,"logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"wp.computingforgeeks.net","chall>
Aug 02 10:05:40 jammy caddy[33989]: {"level":"info","ts":1694426740.800127,"logger":"tls.issuance.acme","msg":"served key authentication","identifier":"wp.computingforgeeks.net","challenge":"http-0>
Aug 02 10:05:40 jammy caddy[33989]: {"level":"info","ts":1694426740.8415916,"logger":"tls.issuance.acme","msg":"served key authentication","identifier":"wp.computingforgeeks.net","challenge":"http->
Aug 02 10:05:40 jammy caddy[33989]: {"level":"info","ts":1694426740.9211166,"logger":"tls.issuance.acme","msg":"served key authentication","identifier":"wp.computingforgeeks.net","challenge":"http->
Aug 02 10:05:41 jammy caddy[33989]: {"level":"info","ts":1694426741.424946,"logger":"tls.issuance.acme.acme_client","msg":"authorization finalized","identifier":"wp.computingforgeeks.net","authz_st>
Aug 02 10:05:41 jammy caddy[33989]: {"level":"info","ts":1694426741.4250467,"logger":"tls.issuance.acme.acme_client","msg":"validations succeeded; finalizing order","order":"https://acme-v02.api.le>
Aug 02 10:05:42 jammy caddy[33989]: {"level":"info","ts":1694426742.0940938,"logger":"tls.issuance.acme.acme_client","msg":"successfully downloaded available certificate chains","count":2,"first_ur>
Aug 02 10:05:42 jammy caddy[33989]: {"level":"info","ts":1694426742.0954115,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"wp.computingforgeeks.net"}
Aug 02 10:05:42 jammy caddy[33989]: {"level":"info","ts":1694426742.095732,"logger":"tls.obtain","msg":"releasing lock","identifier":"wp.computingforgeeks.net"}
Access the WordPress dashboard by visiting.https://example.com
You should get initial wordpress setup page.

Provider username and password.

Thank you for reading our guide on how to Install Caddy web server on an Ubuntu with Let’s Encrypt SSL. I like Caddy simplicity, robustness and the fact that it uses HTTPS by default. No routing and redirects needed to host your website.