How to Install Caddy Web Server on Ubuntu 26.04

Caddy is an open-source web server written in Go that provides automatic HTTPS for all configured domains using Let's Encrypt certificates. It supports static file serving, reverse proxying, and load balancing through a simple configuration syntax called Caddyfile. Caddy handles TLS certificate provisioning and renewal without manual intervention.
This article explains how to install the Caddy web server on an Ubuntu 26.04 server, create a virtual host with automatic HTTPS, and configure firewall rules for HTTP and HTTPS traffic.
Prerequisites
Before you begin, you need to:
- Have access to an Ubuntu 26.04 server instance as a non-root user with sudo privileges.
- Have a domain A record pointing to the server's public IP address. For example,
app.example.com.
Install Caddy
Caddy is not included in the default Ubuntu 26.04 APT repositories. The official Caddy repository provides the latest stable release. The following steps add the repository and install the web server.
Update the APT package index.
console$ sudo apt update
Add the Caddy GPG key to the server's keyring.
console$ 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 Caddy repository to the APT sources.
console$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
Update the package index to include the new repository.
console$ sudo apt update
Install Caddy.
console$ sudo apt install caddy -y
Confirm the installed Caddy version.
console$ caddy version
Your output should be similar to the one below:
v2.11.2 h1:iOlpsSiSKqEW+SIXrcZsZ/NO74SzB/ycqqvAIEfIm64=
Manage the Caddy System Service
The caddy systemd service controls the web server process. The following steps enable automatic startup and demonstrate the core service management commands.
Enable Caddy to start automatically at boot time.
console$ sudo systemctl enable caddy
Start the Caddy service.
console$ sudo systemctl start caddy
Verify that Caddy is active and running.
console$ sudo systemctl status caddy
The output should display
active (running), confirming that the Caddy web server is operational.
Set Up Firewall Rules
Uncomplicated Firewall (UFW) is active by default on Ubuntu 26.04. Caddy requires open ports for HTTP and HTTPS traffic. HTTP port 80 is needed for the ACME challenge during automatic certificate provisioning.
Allow HTTP traffic on port
80.console$ sudo ufw allow 80/tcp
Allow HTTPS traffic on port
443.console$ sudo ufw allow 443/tcp
Create a Caddy Virtual Host
Caddy uses a configuration file called Caddyfile located at /etc/caddy/Caddyfile. Each server block defines a virtual host with a domain, document root, and optional directives. Caddy automatically provisions and renews Let's Encrypt SSL certificates for all configured domains.
Create the web root directory for the virtual host.
console$ sudo mkdir -p /var/www/app.example.com
Create a sample HTML file in the web root directory.
console$ sudo nano /var/www/app.example.com/index.html
Add the following content to the file.
html<html> <head> <title>Caddy Test Page</title> </head> <body> <h1>Hello World from Caddy</h1> </body> </html>
Save and close the file.
Back up the default Caddyfile configuration.
console$ sudo mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.default
Create a new Caddyfile configuration. Replace
app.example.comandadmin@example.comwith your actual domain and email address.console$ sudo nano /etc/caddy/Caddyfile
Add the following configuration to the file.
iniapp.example.com { tls admin@example.com root * /var/www/app.example.com file_server { index index.html } log { output file /var/log/caddy/app.example.com.log format console } }
Save and close the file.
Within the configuration:
app.example.com: Defines the virtual host domain. Caddy automatically provisions an SSL certificate for this domain.tls: Specifies the email address for Let's Encrypt certificate registration.root: Sets the document root directory for serving files.file_server: Enables the static file server withindex.htmlas the default file.log: Writes access and error logs to the specified file.
Create the log directory and assign ownership to the Caddy user.
console$ sudo mkdir -p /var/log/caddy $ sudo chown -R caddy:caddy /var/log/caddy
Format the Caddyfile to ensure consistent indentation and syntax.
console$ sudo caddy fmt --overwrite /etc/caddy/Caddyfile
Validate the Caddyfile configuration for errors.
console$ sudo caddy validate --config /etc/caddy/Caddyfile
The output should display
Valid configuration.Reload Caddy to apply the new configuration.
console$ sudo systemctl reload caddy
Secure the Caddyfile
Restricting file permissions on the Caddyfile prevents unauthorized modifications to the web server configuration. The following steps assign ownership to the Caddy system user and limit access to the configuration file.
Set the Caddy user as the owner of the configuration directory.
console$ sudo chown -R caddy:caddy /etc/caddy
Restrict Caddyfile permissions to the owner only.
console$ sudo chmod 660 /etc/caddy/Caddyfile
Access your domain in a web browser to verify the virtual host and automatic HTTPS. Replace
app.example.comwith your actual domain.https://app.example.comThe browser displays the Hello World from Caddy heading with a valid SSL certificate.
Conclusion
You have installed the Caddy web server on an Ubuntu 26.04 server and configured a virtual host with automatic HTTPS using Let's Encrypt. Caddy handles certificate provisioning and renewal without additional tools or configuration. For more information, refer to the official Caddy documentation.