Caddy is a modern, open-source web server written in Go that automatically provisions and renews TLS certificates via Let’s Encrypt. Unlike Apache or Nginx, Caddy requires almost no manual TLS configuration, making it an excellent choice for developers who want HTTPS out of the box. On RHEL 8, Caddy is not available in the default AppStream repositories, but the project maintains an official COPR repository that integrates cleanly with DNF. This tutorial walks through installing Caddy on RHEL 8, writing a basic Caddyfile, enabling the service, and opening the necessary firewall ports.

Prerequisites

  • A RHEL 8 server with a registered subscription or access to package mirrors
  • A non-root user with sudo privileges, or a root shell
  • A registered domain name with an A record pointing to the server’s public IP (required for automatic TLS)
  • Ports 80 and 443 accessible from the internet
  • Basic familiarity with the command line and systemd

Step 1 — Add the Official Caddy COPR Repository

COPR is Fedora’s community build system and hosts many packages not available in RHEL’s standard repositories. The Caddy project publishes signed builds there. Install the dnf-plugins-core package if it is not already present, then enable the COPR repo.

sudo dnf install -y dnf-plugins-core
sudo dnf copr enable @caddy/caddy

When prompted, confirm the repository key fingerprint. DNF will add a .repo file under /etc/yum.repos.d/ that points to the Caddy COPR mirrors.

Step 2 — Install Caddy

With the repository enabled, install Caddy using DNF. The package creates the caddy system user, places the binary at /usr/bin/caddy, and installs a systemd unit file.

sudo dnf install -y caddy
caddy version

Confirm the version string is printed without errors. The default configuration file location is /etc/caddy/Caddyfile.

Step 3 — Write the Caddyfile

Open the default Caddyfile and replace its contents with a site block that suits your use case. The example below serves static files and proxies a backend application running on port 3000. Replace example.com with your actual domain.

sudo nano /etc/caddy/Caddyfile

Paste the following configuration:

example.com {
    # Serve static files from /var/www/html
    root * /var/www/html
    file_server

    # Reverse proxy API requests to a local backend
    handle /api/* {
        reverse_proxy localhost:3000
    }

    # Automatic HTTPS via Let's Encrypt (default behaviour)
    # TLS email is optional but recommended
    tls [email protected]

    # Compress responses
    encode gzip zstd

    # Access log
    log {
        output file /var/log/caddy/access.log
    }
}

# Redirect bare domain to www (optional)
www.example.com {
    redir https://example.com{uri}
}

Caddy’s site blocks are identified by the hostname. When a public hostname is used, Caddy automatically requests a certificate from Let’s Encrypt on first startup. For local development, use an IP address or :80 as the site address, which disables automatic TLS.

Step 4 — Validate the Configuration

Always validate the Caddyfile before reloading the service to catch syntax errors.

sudo caddy validate --config /etc/caddy/Caddyfile

A successful validation prints Valid configuration. If errors are reported, review the line numbers indicated and correct the Caddyfile.

Step 5 — Enable and Start Caddy

Enable the systemd unit so Caddy starts at boot, then start it immediately.

sudo systemctl enable --now caddy
sudo systemctl status caddy

The status output should show active (running). Check the journal for TLS provisioning messages:

sudo journalctl -u caddy -f

Step 6 — Open Firewall Ports

RHEL 8 uses firewalld as its default firewall manager. Allow HTTP and HTTPS traffic through the public zone, then reload the rules.

sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-services

Verify that both http and https appear in the listed services. Navigate to https://example.com in a browser to confirm that Caddy is serving your site with a valid certificate.

Conclusion

You have installed Caddy on RHEL 8 via the official COPR repository, configured a Caddyfile with static file serving, a reverse proxy, and automatic TLS, validated the configuration, and opened the necessary firewall ports. Caddy’s automatic HTTPS removes the operational burden of manual certificate renewal, making it well-suited for both production sites and staging environments.

Next steps: How to Set Up ModSecurity WAF with Apache on RHEL 8, How to Configure Nginx Rate Limiting on RHEL 8, and How to Enable Brotli and Gzip Compression in Nginx on RHEL 8.