RHEL BasedRocky Linux

How To Install Caddy on Rocky Linux 10

Install Caddy on Rocky Linux 10

Caddy is a modern, open-source web server that has revolutionized the way administrators manage websites and applications. Unlike traditional web servers, Caddy offers automatic HTTPS certificate management through Let’s Encrypt integration, eliminating the tedious manual configuration process. This powerful web server supports HTTP/2 and HTTP/3 protocols, provides a simple configuration syntax, and handles TLS certificate renewal automatically. Rocky Linux 10, an enterprise-grade Linux distribution, provides the perfect foundation for running Caddy in production environments. This comprehensive guide walks you through installing and configuring Caddy web server on Rocky Linux 10, from initial system preparation to advanced configuration options.

What is Caddy Web Server?

Caddy represents a new generation of web servers designed with modern web standards in mind. Developed in Go programming language, Caddy prioritizes security and ease of use without sacrificing performance. The server automatically obtains and renews SSL/TLS certificates from Let’s Encrypt, making HTTPS the default rather than an afterthought. This automation saves countless hours of manual certificate management.

The web server’s configuration file, called Caddyfile, uses human-readable syntax that even beginners can understand quickly. Unlike Apache’s complex directives or Nginx’s block-based configuration, Caddy’s approach feels natural and intuitive. The server excels at serving static content, acting as a reverse proxy, load balancing traffic, and running PHP applications through FastCGI support.

Caddy’s built-in features include automatic HTTP to HTTPS redirection, on-the-fly Markdown rendering, template evaluation, and WebSocket support. The server also implements modern security headers by default, protecting websites from common vulnerabilities without additional configuration. For administrators managing multiple domains, Caddy’s virtual hosting capabilities allow serving different sites from a single server instance with minimal configuration.

Prerequisites

Before beginning the installation process, ensure your system meets the necessary requirements. You need a Rocky Linux 10 server with either a fresh installation or an existing system. Root access or a user account with sudo privileges is essential for executing administrative commands throughout this tutorial.

Basic familiarity with Linux command-line operations helps you follow along smoothly. The server should have at least 1GB of RAM and 10GB of available disk space, though Caddy itself requires minimal resources. An active internet connection is necessary for downloading packages and, optionally, obtaining SSL certificates.

If you plan to test automatic HTTPS functionality, prepare a domain name with proper DNS A or AAAA records pointing to your server’s IP address. The firewall must allow incoming connections on ports 80 and 443 for HTTP and HTTPS traffic respectively. Understanding these prerequisites prevents common installation issues and ensures a smooth setup experience.

Step 1: Update System Packages

Keeping your system up-to-date is the first critical step in any server configuration. Outdated packages may contain security vulnerabilities or compatibility issues that could interfere with Caddy installation. Open your terminal and connect to your Rocky Linux 10 server via SSH.

Execute the following command to update all installed packages to their latest versions:

sudo dnf update -y

This command instructs the DNF package manager to check for available updates across all repositories and install them automatically. The -y flag automatically confirms any prompts, streamlining the update process. Depending on how recently your system was updated, this process may take several minutes to complete.

The system downloads updated packages, verifies their integrity, and installs them in the correct order. You’ll see progress indicators showing which packages are being updated. Once completed, some updates may require a system reboot, particularly kernel updates. Check the command output for any reboot recommendations. If a reboot is suggested, execute sudo reboot and reconnect after the system comes back online.

Step 2: Install DNF COPR Plugin

The Copr (Cool Other Package Repo) system provides community-maintained packages not available in Rocky Linux’s default repositories. Caddy uses this distribution method to provide official packages for Red Hat-based systems like Rocky Linux. Installing the COPR plugin enables your system to access these third-party repositories securely.

Run this command to install the necessary plugin:

sudo dnf install dnf-plugins-core -y

The dnf-plugins-core package includes essential plugins that extend DNF’s functionality beyond basic package management. This collection includes COPR support, repository configuration tools, and debugging utilities. The installation completes quickly since the package is relatively small.

After installation, verify the plugin is available by checking DNF’s plugin list. The system now has the capability to enable COPR repositories, which we’ll use in the next step. This plugin approach maintains system security while allowing access to community-maintained software packages.

Step 3: Enable Caddy Repository

With the COPR plugin installed, you can now enable the official Caddy repository maintained by the Caddy project team. This repository contains the latest stable Caddy releases optimized for Red Hat-based distributions.

Execute the following command to enable the Caddy COPR repository:

sudo dnf copr enable @caddy/caddy -y

When you run this command, the system contacts the COPR infrastructure to retrieve repository configuration details. The -y flag automatically accepts the repository addition without prompting for confirmation. You’ll see a message explaining that COPR repositories are community-maintained and asking you to review the repository details.

The system downloads the repository metadata and configures your package manager to recognize Caddy packages. This repository configuration persists across system reboots, ensuring you receive Caddy updates through your normal system update process. The official Caddy COPR repository is actively maintained and provides timely security updates.

Verify the repository was added successfully by listing your enabled repositories:

sudo dnf repolist | grep caddy

You should see the Caddy COPR repository in the output, confirming it’s ready for use.

Step 4: Install Caddy Web Server

Now comes the main installation step. With the repository configured, installing Caddy is straightforward and follows standard DNF package installation procedures.

Install Caddy with this command:

sudo dnf install caddy -y

DNF resolves dependencies automatically, downloading Caddy and any required libraries. The installation process typically completes within a minute, depending on your connection speed. The Caddy package includes the main server binary, default configuration files, systemd service definitions, and documentation.

Once installation finishes, verify Caddy installed correctly by checking its version:

caddy version

This command displays the installed Caddy version number, confirming the binary is accessible and functional. You should see output similar to “v2.7.x” or whatever the current stable version is. The version command also shows build information and platform details.

The installation creates several important directories and files. The main Caddy binary resides in /usr/bin/caddy. Configuration files live in /etc/caddy/, with the primary configuration file being /etc/caddy/Caddyfile. The default web root directory is /usr/share/caddy, though you can customize this location based on your preferences.

Step 5: Start and Enable Caddy Service

Rocky Linux 10 uses systemd for service management, providing robust control over background processes. You need to start the Caddy service and configure it to launch automatically during system boot.

Start the Caddy service immediately with this command:

sudo systemctl start caddy

This command initiates the Caddy web server using your system’s current configuration. The service starts in the background, listening on configured ports for incoming connections. Starting the service doesn’t enable it permanently, so it won’t automatically restart after a reboot unless you complete the next step.

Enable Caddy to start automatically on system boot:

sudo systemctl enable caddy

Enabling the service creates symbolic links in systemd’s startup directories, ensuring Caddy launches during the boot sequence. This configuration persists across reboots, providing continuous service availability.

Check the service status to confirm everything is running correctly:

sudo systemctl status caddy

The status command displays comprehensive information about the Caddy service. Look for “active (running)” in green text, indicating the service is operating normally. The output also shows the process ID (PID), memory usage, and recent log entries. If you see “inactive (dead)” or “failed” status, the service encountered problems during startup.

For troubleshooting startup issues, examine the full service logs:

sudo journalctl -u caddy -n 50

This command displays the last 50 log entries for the Caddy service, helping you identify configuration errors or permission issues that prevent proper startup.

Step 6: Configure Firewall Rules

Rocky Linux 10 includes firewalld by default, protecting your server by blocking unauthorized network connections. You must explicitly allow HTTP and HTTPS traffic for your web server to be accessible from external networks.

Allow HTTP traffic on port 80:

sudo firewall-cmd --add-service=http --permanent

This command adds a permanent rule allowing incoming HTTP connections. The --permanent flag ensures the rule persists across firewall reloads and system reboots. Without this flag, the rule would only apply to the current session.

Allow HTTPS traffic on port 443:

sudo firewall-cmd --add-service=https --permanent

HTTPS is essential for secure connections and Caddy’s automatic certificate management. Opening port 443 allows Let’s Encrypt’s validation servers to verify your domain ownership during certificate issuance.

Reload the firewall configuration to apply the changes:

sudo firewall-cmd --reload

Reloading activates your new rules without interrupting existing connections. The firewall immediately begins accepting traffic on the newly opened ports.

Verify your firewall rules are active:

sudo firewall-cmd --list-services

You should see both “http” and “https” in the output, confirming your web server ports are accessible. If you’re using custom ports instead of the standard 80 and 443, adjust your firewall rules accordingly using --add-port=<port>/tcp syntax.

Rocky Linux’s SELinux security layer may also restrict Caddy’s operations. If you encounter permission issues, check SELinux status and audit logs for denials. Most standard Caddy configurations work with SELinux enforcing mode, but custom setups may require policy adjustments.

Step 7: Verify Caddy Installation

Testing your installation confirms that Caddy is running and accessible over the network. Open a web browser on any device connected to the internet and navigate to your server’s IP address.

Enter the following URL in your browser’s address bar:

http://your-server-ip-address

Replace “your-server-ip-address” with your actual server IP. If everything is configured correctly, you’ll see Caddy’s default welcome page. This page confirms that Caddy is receiving HTTP requests and responding appropriately.

If you have a domain name configured with proper DNS records pointing to your server, test with the domain name instead:

http://yourdomain.com

Using a domain name allows you to test Caddy’s automatic HTTPS functionality later. The initial HTTP request helps verify basic connectivity before introducing TLS complexity.

For command-line verification, use curl from your server or another machine:

curl http://your-server-ip-address

This command retrieves the HTML content Caddy serves, displaying it in your terminal. Successful output confirms network connectivity and proper service operation.

Check that Caddy is listening on the expected ports:

sudo ss -tlnp | grep caddy

This command shows all TCP listening sockets associated with the Caddy process. You should see entries for ports 80 and 443, indicating Caddy is ready to accept connections.

Understanding Caddy File Structure

Familiarity with Caddy’s file structure helps you manage configurations and troubleshoot issues effectively. The main configuration file, called the Caddyfile, resides at /etc/caddy/Caddyfile. This human-readable text file defines how Caddy handles incoming requests, which domains it serves, and what features to enable.

The default web root directory is /usr/share/caddy, containing the welcome page you saw during verification. For production use, administrators typically create custom web root directories like /srv/www/html or /var/www/html to organize content better. You can configure multiple web roots for different virtual hosts within a single Caddyfile.

Caddy stores automatically obtained TLS certificates in /var/lib/caddy/.local/share/caddy. This directory contains Let’s Encrypt certificates, private keys, and account information. The systemd service file defining how Caddy runs as a service lives at /usr/lib/systemd/system/caddy.service.

Log files provide valuable information for troubleshooting and monitoring. Caddy integrates with systemd’s journal, so logs are accessible through journalctl commands. For applications requiring separate log files, you can configure custom logging destinations in your Caddyfile.

Understanding ownership and permissions is crucial. The Caddy service runs as the “caddy” user and group, a non-privileged account created during installation. This security measure limits potential damage if the web server is compromised. Configuration files should be owned by root but readable by the caddy user.

Basic Caddy Configuration

Customizing Caddy’s configuration unlocks its full potential for serving your specific content and applications. The Caddyfile uses an intuitive syntax that’s easier to learn than traditional web server configurations.

Create a custom web root directory for your content:

sudo mkdir -p /srv/www/html

This command creates the directory structure, including any missing parent directories. Using /srv/www/html follows Linux filesystem hierarchy standards for served data.

Set appropriate ownership for the web directory:

sudo chown -R caddy:caddy /srv/www/html

The Caddy service runs as the “caddy” user, so this user needs read access to serve files. The recursive flag ensures all subdirectories and files inherit the correct ownership.

Configure SELinux context for the custom directory on Rocky Linux:

sudo chcon -t httpd_sys_content_t /srv/www/html -R

SELinux requires specific security contexts for web content. The httpd_sys_content_t type allows web servers to read files in this directory. Without this context, SELinux blocks Caddy from accessing your content even with correct filesystem permissions.

For persistent SELinux context across system relabeling:

sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www/html(/.*)?"
sudo restorecon -R -v /srv/www/html

Edit the Caddyfile to point to your custom web root:

sudo nano /etc/caddy/Caddyfile

Replace the default configuration with a basic setup:

:80 {
    root * /srv/www/html
    file_server
}

This configuration tells Caddy to listen on port 80 for all IP addresses, serve files from /srv/www/html, and enable the file server directive. The asterisk in “root *” applies the root directory to all requests.

Test your configuration for syntax errors before applying it:

caddy validate --config /etc/caddy/Caddyfile

Validation catches configuration mistakes before they cause service failures. Only proceed if validation returns no errors.

Restart Caddy to apply the new configuration:

sudo systemctl restart caddy

Create a simple test page to verify your configuration works:

echo "<h1>Welcome to Caddy on Rocky Linux 10</h1>" | sudo tee /srv/www/html/index.html

Access your server’s IP address in a browser to see your custom content.

Configuring Automatic HTTPS

Caddy’s automatic HTTPS feature distinguishes it from traditional web servers. When you specify a domain name in your Caddyfile, Caddy automatically obtains, installs, and renews SSL/TLS certificates from Let’s Encrypt.

Before enabling automatic HTTPS, ensure your domain’s DNS records point correctly to your server’s IP address. Create an A record for IPv4 addresses or an AAAA record for IPv6 addresses. DNS propagation may take several hours, so verify resolution using:

nslookup yourdomain.com

Edit your Caddyfile to use your domain name:

sudo nano /etc/caddy/Caddyfile

Replace the configuration with:

yourdomain.com {
    root * /srv/www/html
    file_server
}

Simply using your domain name instead of a port number triggers automatic HTTPS. Caddy handles the entire certificate lifecycle without additional configuration. The server automatically redirects HTTP requests to HTTPS, ensuring secure connections.

Restart Caddy to initiate certificate acquisition:

sudo systemctl restart caddy

During the first start with a domain configuration, Caddy contacts Let’s Encrypt’s servers, proves domain ownership through HTTP-01 or TLS-ALPN-01 challenges, and receives signed certificates. This process requires ports 80 and 443 to be accessible from the internet.

Monitor the process through logs:

sudo journalctl -u caddy -f

You’ll see messages about certificate acquisition and installation. Successful certificate issuance results in your site being accessible via HTTPS immediately.

Test your HTTPS configuration by visiting:

https://yourdomain.com

Your browser should show a valid certificate without security warnings. Caddy automatically renews certificates before expiration, typically 30 days before the 90-day Let’s Encrypt certificate expires.

Certificate files are stored in /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/. Caddy manages these files automatically, requiring no manual intervention for renewals.

Advanced Configuration Options

Caddy’s flexibility extends far beyond serving static files. The web server excels as a reverse proxy, forwarding requests to backend applications running on different ports.

Configure a reverse proxy to a backend service:

yourdomain.com {
    reverse_proxy localhost:8080
}

This configuration forwards all requests to an application running on port 8080, useful for Node.js, Python, or Go applications.

Implement load balancing across multiple backend servers:

yourdomain.com {
    reverse_proxy backend1.local:8080 backend2.local:8080 backend3.local:8080 {
        lb_policy round_robin
    }
}

Caddy distributes requests evenly across backend servers, improving reliability and performance.

Configure PHP support using FastCGI:

yourdomain.com {
    root * /srv/www/html
    php_fastcgi unix//run/php-fpm/www.sock
    file_server
}

This setup works with PHP-FPM, enabling PHP application hosting.

Set up virtual hosting for multiple domains:

site1.com {
    root * /srv/www/site1
    file_server
}

site2.com {
    root * /srv/www/site2
    file_server
}

Each domain serves content from its own directory.

Enable gzip compression to reduce bandwidth:

yourdomain.com {
    encode gzip
    root * /srv/www/html
    file_server
}

Compression significantly reduces transfer sizes for text-based content.

Add security headers for enhanced protection:

yourdomain.com {
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
    root * /srv/www/html
    file_server
}

These headers protect against common web vulnerabilities.

Testing Your Caddy Setup

Thorough testing ensures your web server configuration meets your requirements and performs reliably. Create a test HTML file with more complex content:

sudo nano /srv/www/html/test.html

Add sample content:

<!DOCTYPE html>
<html>
<head>
    <title>Caddy Test Page</title>
</head>
<body>
    Caddy is Working!
    <p>Your web server is properly configured on Rocky Linux 10.</p>
</body>
</html>

Copy Caddy’s default welcome page to your custom web root if needed:

sudo cp /usr/share/caddy/index.html /srv/www/html/

This provides a professional landing page while you develop your actual content.

After making configuration changes, reload Caddy gracefully:

sudo systemctl reload caddy

Reloading applies configuration changes without dropping existing connections.

Test from multiple devices and networks to ensure accessibility. Use browser developer tools to inspect HTTP headers, verify HTTPS is working, and check for mixed content warnings. Command-line testing with curl provides detailed connection information:

curl -I https://yourdomain.com

The -I flag shows only headers, revealing status codes, content types, and security headers.

Verify certificate validity and expiration:

echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates

This command displays your certificate’s issuance and expiration dates.

Performance testing helps establish baseline metrics. Tools like Apache Bench measure request handling capacity:

ab -n 1000 -c 10 http://yourdomain.com/

This sends 1000 requests with 10 concurrent connections, showing response times and throughput.

Common Troubleshooting Tips

Even with careful configuration, issues occasionally arise. Understanding common problems and their solutions minimizes downtime.

Service won’t start: Check for configuration syntax errors using caddy validate. Review logs with sudo journalctl -u caddy -xe for specific error messages. Port conflicts with other web servers like Apache or Nginx prevent Caddy from binding to ports 80 or 443. Stop conflicting services or configure Caddy to use alternative ports.

Firewall blocking connections: Verify firewall rules are active and correctly configured. Test from external networks, as connections from localhost may bypass firewall restrictions. Cloud providers often implement additional security groups requiring separate configuration.

SELinux permission denials: Check audit logs for SELinux blocks using sudo ausearch -m avc -ts recent. Set correct security contexts for web root directories. In development environments, you can temporarily set SELinux to permissive mode for testing, though this isn’t recommended for production.

Certificate acquisition failures: Ensure your domain’s DNS records are correct and propagated. Verify ports 80 and 443 are accessible from the internet for Let’s Encrypt validation. Rate limits from Let’s Encrypt may temporarily prevent certificate issuance if you’ve made too many requests. Check Caddy logs for specific ACME errors.

Configuration not applying: After editing the Caddyfile, reload or restart the service. Validate syntax before reloading to catch errors early. Some changes require a full restart rather than just a reload.

File permission issues: Ensure the caddy user can read all files in your web root. Directories need execute permission for the caddy user to access their contents. Use ls -la to inspect permissions and ownership.

Monitor logs continuously while troubleshooting:

sudo journalctl -u caddy -f

This real-time log view helps identify issues as they occur.

Caddy Management Commands

Regular server management requires familiarity with systemd service control commands. These commands provide complete control over the Caddy service lifecycle.

Start Caddy when it’s stopped:

sudo systemctl start caddy

Stop Caddy completely, terminating all connections:

sudo systemctl stop caddy

Restart Caddy, briefly interrupting service:

sudo systemctl restart caddy

Use restart after major configuration changes or when applying updates.

Reload configuration without dropping connections:

sudo systemctl reload caddy

Reloading is preferable for configuration updates as it maintains active connections.

Check current service status:

sudo systemctl status caddy

View comprehensive service logs:

sudo journalctl -u caddy

Add -f to follow logs in real-time, or -n 100 to show the last 100 lines.

Test Caddyfile syntax without affecting the running service:

caddy validate --config /etc/caddy/Caddyfile

Format your Caddyfile with proper indentation:

caddy fmt --overwrite /etc/caddy/Caddyfile

Formatting improves readability and helps catch syntax errors.

Security Best Practices

Securing your web server protects your data and your users. Keep Caddy updated to receive security patches:

sudo dnf update caddy

Regular updates address vulnerabilities discovered after release.

Restrict Caddyfile permissions to prevent unauthorized modification:

sudo chmod 644 /etc/caddy/Caddyfile
sudo chown root:root /etc/caddy/Caddyfile

Only root should write to configuration files, though the caddy user needs read access.

Configure SELinux properly rather than disabling it. SELinux provides mandatory access control that significantly enhances security. Learn to work with SELinux rather than against it.

Implement rate limiting to prevent abuse:

yourdomain.com {
    rate_limit {
        zone dynamic {
            key {remote_host}
            events 100
            window 1m
        }
    }
    root * /srv/www/html
    file_server
}

This limits each IP address to 100 requests per minute.

Enable security headers as shown in the advanced configuration section. Headers like HSTS, CSP, and X-Frame-Options protect against various attack vectors.

Regularly audit your configuration for unnecessary features or exposed endpoints. Disable directory listing unless specifically needed. Monitor access logs for suspicious patterns indicating scanning or exploitation attempts.

Maintain backups of your Caddyfile and web content. Store backups in separate locations to protect against server failures. Automate backups using scripts and cron jobs.

Consider implementing fail2ban to automatically block IP addresses showing malicious behavior patterns. This tool monitors logs and creates temporary firewall rules against attackers.

Congratulations! You have successfully installed Caddy. Thanks for using this tutorial for installing the Caddy web server on Rocky Linux 10 system. For additional help or useful information, we recommend you check the official Caddy website.

VPS Manage Service Offer
If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal!

r00t

r00t is an experienced Linux enthusiast and technical writer with a passion for open-source software. With years of hands-on experience in various Linux distributions, r00t has developed a deep understanding of the Linux ecosystem and its powerful tools. He holds certifications in SCE and has contributed to several open-source projects. r00t is dedicated to sharing her knowledge and expertise through well-researched and informative articles, helping others navigate the world of Linux with confidence.
Back to top button