Install Caddy Web Server on Ubuntu / Debian

Welcome to our today’s article, the intention of this article is to help you understand the installation and configuration of Caddy web server on Ubuntu | Debian. Caddy is an open-source, efficiency application that is designed to be quick, simple to use, and increase productivity. Caddy is compatible with Operating Systems such Linux, BSD, Windows, Mac, Solaris, and Android platforms.

Caddy Web Server Features

  • It’s suitable for both dynamic and static websites.
  • Caddy reloads with no downtime.
  • Caddyfile allows for simple configuration and management.
  • It is safe to use – By default, HTTPS is enabled (through Let’s Encrypt).
  • Caddy is developed in the Go programming language and has no external dependencies . The binary is self-contained and may be executed on any platform, including containers.
  • Cady is set up to use HTTP/2 by default.
  • Using virtual hosting, you may host several websites.
  • For more secure communications, TLS session ticket key rotation is used.
  • Plugins can be used to enhance its capabilities.

Install Caddy Web Server on Ubuntu | Debian

1. Install Caddy Web Server

Caddy may be installed in a number of methods, including through Docker, official repositories, or compiling from source. If you need functionality that can only be introduced via a third-party module/plugin, the building from source technique is handy.
We’ll use the official Caddy repository for Ubuntu/Debian-based computers in this tutorial.

Install dependencies:

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 the Repository to the top of the list for the Stable release of Caddy:

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:

sudo apt update && sudo apt install caddy

The following command can be used to validate the installation;

$ caddy version
v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=

Check Caddy binary location.

$ which caddy
/usr/bin/caddy
Running Caddy as not-root user

As a non-root user, allow the caddy binary to connect to privileged ports (e.g. 80, 443):

sudo setcap 'cap_net_bind_service=+ep' /usr/bin/caddy

Run the following command to create the necessary users, groups, and directories:

sudo groupadd -g 33 www-data
sudo useradd \
  -g www-data --no-user-group \
  --home-dir /var/www --no-create-home \
  --shell /usr/sbin/nologin \
  --system --uid 33 www-data

sudo mkdir /etc/caddy
sudo chown -R root:root /etc/caddy
sudo mkdir /etc/ssl/caddy
sudo chown -R root:www-data /etc/ssl/caddy
sudo chmod 0770 /etc/ssl/caddy

After successful installation of Caddy web server, check the status as follows;

$ sudo systemctl status caddy.service
● caddy.service - Caddy
     Loaded: loaded (/usr/lib/systemd/system/caddy.service; enabled; preset: enabled)
     Active: active (running) since Fri 2025-03-28 17:42:05 UTC; 7min ago
       Docs: https://caddyserver.com/docs/
   Main PID: 1846 (caddy)
      Tasks: 7 (limit: 4614)
     Memory: 11.0M (peak: 12.2M)
        CPU: 69ms
     CGroup: /system.slice/caddy.service
             └─1846 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile

Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"warn","ts":1743183725.0463705,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will >
Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"info","ts":1743183725.0464666,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000363f0>
Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"warn","ts":1743183725.0466588,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"warn","ts":1743183725.0466678,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"info","ts":1743183725.0466733,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"info","ts":1743183725.0468793,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"info","ts":1743183725.0469365,"msg":"serving initial configuration"}
Mar 28 17:42:05 ubuntu-01 systemd[1]: Started caddy.service - Caddy.
Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"info","ts":1743183725.0568397,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/var/lib/caddy/.local/share/caddy"}
Mar 28 17:42:05 ubuntu-01 caddy[1846]: {"level":"info","ts":1743183725.0603573,"logger":"tls","msg":"finished cleaning storage units"}

2. Using Caddy Web Server to Host Applications

To host applications using Caddy Web Server, you need to install PHP and Database i.e MariaDB.

Install PHP

Run the following commands to install PHP and its plugins.

sudo apt install php-fpm php-mysql php-curl php-gd php-mbstring php-common php-xml php-xmlrpc
Install MariaDB Database Server

Install and configure MariaDB database server as follow;

sudo apt install mariadb-server mariadb-client

Configure MariaDB Database.

$ sudo mariadb-secure-installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):  <ENTER>
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] y
Enabled successfully!
Reloading privilege tables..
 ... Success!


You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] y
New password: <INPUT-PASSWORD>
Re-enter new password: <CONFIRM-PASSWORD>
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

After installing MariaDB database, you can check if it’s running using the following command:

$ sudo systemctl status mariadb
● mariadb.service - MariaDB 10.11.8 database server
     Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: enabled)
     Active: active (running) since Fri 2025-03-28 17:51:05 UTC; 1min 5s ago
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
   Main PID: 13070 (mariadbd)
     Status: "Taking your SQL requests now..."
      Tasks: 10 (limit: 30453)
     Memory: 78.8M (peak: 81.9M)
        CPU: 376ms
     CGroup: /system.slice/mariadb.service
             └─13070 /usr/sbin/mariadbd

Mar 28 17:51:05 ubuntu-01 mariadbd[13070]: 2025-03-28 17:51:05 0 [Note] Plugin 'FEEDBACK' is disabled.
Mar 28 17:51:05 ubuntu-01 mariadbd[13070]: 2025-03-28 17:51:05 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
Mar 28 17:51:05 ubuntu-01 mariadbd[13070]: 2025-03-28 17:51:05 0 [Warning] You need to use --log-bin to make --expire-logs-days or --binlog-expire-logs-seconds work.
Mar 28 17:51:05 ubuntu-01 mariadbd[13070]: 2025-03-28 17:51:05 0 [Note] InnoDB: Buffer pool(s) load completed at 250328 17:51:05
Mar 28 17:51:05 ubuntu-01 mariadbd[13070]: 2025-03-28 17:51:05 0 [Note] Server socket created on IP: '127.0.0.1'.
Mar 28 17:51:05 ubuntu-01 mariadbd[13070]: 2025-03-28 17:51:05 0 [Note] /usr/sbin/mariadbd: ready for connections.
Mar 28 17:51:05 ubuntu-01 mariadbd[13070]: Version: '10.11.8-MariaDB-0ubuntu0.24.04.1'  socket: '/run/mysqld/mysqld.sock'  port: 3306  Ubuntu 24.04
Mar 28 17:51:05 ubuntu-01 systemd[1]: Started mariadb.service - MariaDB 10.11.8 database server.
Mar 28 17:51:05 ubuntu-01 /etc/mysql/debian-start[13087]: Upgrading MariaDB tables if necessary.
Mar 28 17:51:05 ubuntu-01 /etc/mysql/debian-start[13098]: Checking for insecure root accounts.
Hosting PHP Application on Caddy Web Server

The file /etc/php/Version/fpm/pool.d/www.conf must be configured. To edit the file, open it;

sudo vim /etc/php/*/fpm/pool.d/www.conf

Find the lines in the file that say user=www-data and group=www-data and change them to caddy;

user = caddy
group = caddy

Also, in the file, change the lines listen.owner=www-data and listen.group=www-data to caddy;

listen.owner = caddy
listen.group = caddy

Now restart the PHP-fpm process;

sudo systemctl restart php8.3-fpm
Configure Caddy to Host PHP File

Create the site’s root directory first:

sudo mkdir -p /var/www/html/php

Caddy created a default Caddyfile at /etc/caddy/Caddyfile during installation. Edit it as follows:

sudo vim /etc/caddy/Caddyfile

Add the following contents to the file;

example.com {
    root * /var/www/html/php
    encode gzip zstd
    php_fastcgi unix//run/php/php-fpm.sock
   
    tls [email protected] {
    	protocols tls1.2 tls1.3    	
    }
}

Caddy server must be restarted in order for the changes in the Caddyfile we created above to take effect:

sudo systemctl restart caddy

Run the PHP application i.e Hello World on Caddy as follows, create a PHP file app.php on /var/www/html/php directory;

sudo vim /var/www/html/php/app.php

Add the following contents to the file created above;

<html>
<body>
<div style="width: 100%; font-size: 40px; font-weight: bold; text-align:center;">
<?php
    print "Hello World";
?>
</div>
</body>
</html>

In your web browser, go to https://example.com/app.php and you should see something like this:

Using Caddy Web Server to host WordPress Website

On Ubuntu | Debian, we’ll look at an example of hosting a WordPress-powered website with Caddy web server.

Login to the server:

$ mysql -u root -p
Enter password:<ENTER PASSWORD>
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 31
Server version: 10.6.12-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

Create a database for WordPress in MariaDB as the root user:

CREATE DATABASE WordPressDB;
GRANT ALL PRIVILEGES ON WordPressDB.* to 'wp_user'@'localhost' IDENTIFIED BY 'StrongPassword';
FLUSH PRIVILEGES;
QUIT;
Download WordPress and Install

Now download WordPress and unzip the archive:

sudo wget http://wordpress.org/latest.tar.gz
tar xvf latest.tar.gz

The tar command above will extract the whole contents of the tarball to the wordpress folder in your working directory.

Move the wordpress folder to /var/www/html directory:

sudo mv wordpress /var/www/html

Change the user and group ownership permissions to www-data:

sudo chown -R www-data:www-data /var/www/html/wordpress

Now we’ll set up the database connection for WordPress:

sudo mv /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php

Edit the file wp-config.php to configure:

sudo vim /var/www/html/wordpress/wp-config.php

Configure as follows:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'WordPressDB');

/** MySQL database username */
define('DB_USER', 'wp_user');

/** MySQL database password */
define('DB_PASSWORD', 'StrongPassword');

/** MySQL 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 now need to configure Caddy Web server to serve our WordPress website, as we have completed the WordPress installation. Create a Caddy configuration file in /etc/caddy/Caddyfile to begin.

sudo vim /etc/caddy/Caddyfile

Add the content below:

example.com {
    root * /var/www/html/wordpress
    encode gzip zstd
    php_fastcgi unix//run/php/php-fpm.sock

    tls [email protected] {
        protocols tls1.2 tls1.3
    }
}

Replace example.com with your WordPress website’s actual domain and [email protected] with the email address you used to get the Let’s Encrypt certificate. To support php, we use php-fpm via fastcgi.

Restart caddy service:

sudo systemctl restart caddy.service

If the start was successful, you should get a successful message:

systemctl status caddy.service

Visit https://example.com to get to the WordPress dashboard. You should go to the WordPress setup page for the first time:

Finally, provider username and password to login:

Conclusion

Thank you for taking the time to read our tutorial on how to set up Caddy web server on Ubuntu 24.04 and Debian 12. Caddy appeals to me because of its simplicity, robustness, and the fact that it defaults to HTTPS. To host your website, you won’t require any routing or redirects.

Cool Articles:

Your IT Journey Starts Here!

Ready to level up your IT skills? Our new eLearning platform is coming soon to help you master the latest technologies.

Be the first to know when we launch! Join our waitlist now.

Join our Linux and open source community. Subscribe to our newsletter for tips, tricks, and collaboration opportunities!

Recent Post

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Post

In this tutorial, we are going to look at how to install Jenkins on Ubuntu 24.04|22.04. First, let us learn […]

Can I install and Use PowerShell on my macOS?. PowerShell is a cross-platform task automation and configuration management framework, consisting of […]

Fish, short for Friendly Interactive Shell, is an easy to install and use shell for Unix systems. The shell comes […]

Let's Connect

Unleash the full potential of your business with CloudSpinx. Our expert solutions specialists are standing by to answer your questions and tailor a plan that perfectly aligns with your unique needs.
You will get a response from our solutions specialist within 12 hours
We understand emergencies can be stressful. For immediate assistance, chat with us now

Contact CloudSpinx today!

Download CloudSpinx Profile

Discover the full spectrum of our expertise and services by downloading our detailed Company Profile. Simply enter your first name, last name, and email address.