---
title: "Automating Site Deployments with Caddy Web Server"
description: "Learn to streamline site deployments with Caddy web server. Simplify setup, automate tasks, and boost efficiency with this comprehensive tutorial!"
canonical: "https://adamtheautomator.com/caddy-web-server/"
---

# Automating Site Deployments with Caddy Web Server

> Learn to streamline site deployments with Caddy web server. Simplify setup, automate tasks, and boost efficiency with this comprehensive tutorial!

Source: https://adamtheautomator.com/caddy-web-server/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![Automating Site Deployments with Caddy Web Server](https://adamtheautomator.com/wp-content/uploads/2024/04/caddy-web-server-2.jpg)

# Automating Site Deployments with Caddy Web Server

[![](https://secure.gravatar.com/avatar/b1faae2f957a0d43de36dfd25e8c08537718fb87c49cfd0a15b0e860a7f7b9a0?s=192&d=mm&r=g)Mercy Bassey](https://adamtheautomator.com/author/mercy-bassey/)3 April 20246 min. read

Categories: [DevOps](/category/devops/)

Tags:[Web Development](/tag/web-development/)

Table of Contents

*   [Prerequisites](#prerequisites)
*   [Installing the Caddy Web Server on Ubuntu](#installing-the-caddy-web-server-on-ubuntu)
*   [Serving Up a Static HTML File](#serving-up-a-static-html-file)
*   [Transforming Caddy as a Reverse Proxy](#transforming-caddy-as-a-reverse-proxy)
*   [Conclusion](#conclusion)

Web servers have been the backbone of the internet, delivering content to users worldwide. But then again, security has always been a top concern in this process. Fear not, as the Caddy web server has got your back, armed and secure from the get-go.

In this tutorial, you will journey into the heart of the Caddy web server and learn the ins and outs of site deployments.

Ready? Let Caddy automate your site deployments and embrace a hassle-free, secure web-serving experience!

## Prerequisites

Before jumping into automating site deployments with Caddy, ensure you have the following in place:

*   An Ubuntu server to run Caddy – This tutorial uses an Ubuntu 22.04LTS, but other distros work.

Related:[Install Ubuntu Server 20.04: A Step-by-Step Walkthrough](https://adamtheautomator.com/install-ubuntu/)

*   A non-root user with sudo privileges.

> 💡 _This tutorial uses the root account for running commands, which is not the best practice from a security standpoint. Switching to a non-root user with sudo privileges is preferable for executing similar actions on your system._

Related:[How to Create a User on Ubuntu Linux in Multiple Ways](https://adamtheautomator.com/create-user-on-ubuntu/)

*   [pip3](https://www.educative.io/answers/installing-pip3-in-ubuntu) and [Flask](https://flask.palletsprojects.com/en/3.0.x/installation/) installed on your Ubuntu server.
    
*   A domain name (i.e., _mercyio.xyz_) that points your domain’s A/AAAA DNS records to your server.
    

## Installing the Caddy Web Server on Ubuntu

Imagine you have set up your system but still need the perfect tool to manage your site deployments effortlessly. Look no further than Caddy to serve your content flawlessly and automate various aspects of your deployment process.

To install Caddy on your Ubuntu system, you must obtain a Caddy binary and install Caddy as a system service as follows:

> 💡 _Note: This installation is for Debian, Ubuntu, and Raspbian. If you are on a different distro, visit the [official documentation](https://caddyserver.com/docs/install) for installing Caddy._

1\. Open your terminal, then execute the following command to `install` the necessary components for managing packages in a Debian-based system.

This installation includes the following:

*   `debian-keyring` – Contains GnuPG archive keys for the Debian archive to verify Debian packages’ authenticity during installation or update.
*   `debian-archive-keyring` – Contains the Debian archive keyring for package authentication and integrity verification.
*   `apt-transport-https` – Provides support for securely downloading packages via HTTPS in APT.
*   [`curl`](https://adamtheautomator.com/curl-linux/)– A command-line tool for transferring data with URLs that supports various protocols, including HTTP and HTTPS. This tool is used to download files from remote servers.

> 💡 _If you use a non-root user, always prepend commands with `sudo` if they require elevated privileges._

```bash
apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
```

![caddy web server-Installing necessary components for package management](https://adamtheautomator.com/wp-content/uploads/2024/04/image-5.png)

Installing necessary components for package management

2\. After package installations, run the command below, which provides no output but performs the following:

*   Fetch (`curl`) the GPG key for the Caddy package repository. This GPG key verifies the authenticity of packages downloaded from the Caddy repository.
*   Converts the GPG key into a binary format and saves the binary to a specific file location.

```bash
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
```

3\. Subsequently, run this command to achieve the following:

*   Fetch (`curl`) the content of a text file from a specified URL, which contains the information necessary for adding the Caddy package repository to your system’s APT sources.  
    This file inclusion allows users to install or update Caddy packages using the system’s package manager.
*   Write the fetched content to a file named `caddy-stable.list` located in the `/etc/apt/sources.list.d/` directory.

```bash
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \| tee /etc/apt/sources.list.d/caddy-stable.list
```

![Fetching a file to allow installing or updating Caddy packages](https://adamtheautomator.com/wp-content/uploads/2024/04/image-4.png)

Fetching a file to allow installing or updating Caddy packages

4\. Now, execute the following `apt update` command to ensure your system’s package lists are up-to-date.

```bash
apt update
```

Related:[Ubuntu Apt Get Mastery: A Guide with Practical Examples](https://adamtheautomator.com/ubuntu-apt-get/)

![Updating the system’s package list](https://adamtheautomator.com/wp-content/uploads/2024/04/image-3.png)

Updating the system’s package list

5\. Once updated, run the command below to `install` the `caddy` web server package on your system and check the installed `version`.

```bash
apt install caddycaddy version
```

As of this writing, the latest version is **v2.7.6;** yours might be different.

![Installing the Caddy web server package and checking the installed version](https://adamtheautomator.com/wp-content/uploads/2024/04/image-2.png)

Installing the Caddy web server package and checking the installed version

6\. Invoke the following `systemctl` command to verify the `status` of the `caddy` web server.

```bash
systemctl status caddy
```

If you have successfully installed Caddy, it starts and becomes active, and you will see the following output.

![Verifying the Caddy web server status ](https://adamtheautomator.com/wp-content/uploads/2024/04/image-1.png)

Verifying the Caddy web server status

Related:[Correct Way of Using Ubuntu systemctl to Control Systemd](https://adamtheautomator.com/ubuntu-systemctl/)

7\. Lastly, open your favorite web browser and visit your server address, followed by port `80` (i.e., _172.x.x.x:80_) to access the Caddy welcome page.

![Accessing the Caddy web page](https://adamtheautomator.com/wp-content/uploads/2024/04/image.png)

Accessing the Caddy web page

## Serving Up a Static HTML File

With your Caddy server up, you must lay the groundwork for hosting your website or web application efficiently, ensuring Caddy can serve a static HTML file.

To make Caddy serve up a static HTML file, follow these steps:

1\. Open the _/etc/caddy/Caddyfile_ with your preferred editor (i.e., `nano` or [`vim`](https://adamtheautomator.com/vim-for-linux/)).

![Opening the Caddyfile ](https://adamtheautomator.com/wp-content/uploads/2024/04/image-9.png)

Opening the Caddyfile

Related:[How to Get Started With Gedit Linux](https://adamtheautomator.com/gedit-linux/)

2\. Next, delete and replace all contents of the file with the following lines, replacing `domain.com` with your domain name.

This configuration tells Caddy to serve out static files found in the `/var/www/html` directory when someone visits your specified domain (`domain.com`).

```
# Replace this with your domain namedomain.com # Set the root directory for serving files to /var/www/htmlroot * /var/www/html# Enable the file server functionalityfile_server
```

![Editing the Caddyfile to serve a static HTML file](https://adamtheautomator.com/wp-content/uploads/2024/04/image-8.png)

Editing the Caddyfile to serve a static HTML file

3\. Afterward, run each command below to establish a directory where your website’s files will be stored.

```bash
# Create the directory /var/www/html if it doesn't exist alreadymkdir -p /var/www/html# Navigate to the /var/www/html directorycd /var/www/html# Create an empty index.html file (your homepage)touch index.html
```

4\. Open the _index.html_ file within the _/var/www/html_ directory and replace the content with the following code for ctote a basic webpage.

Modify the content as you like; this file will be your domain’s default page.

```markup
<!DOCTYPE html><html lang='en'><head>    <meta charset='UTF-8'>    <meta name='viewport' content='width=device-width, initial-scale=1.0'>    <title>Welcome to My Site</title></head><body>    <header>        <h1>Hello from Caddy Server!</h1>    </header>    <main>        <p>Welcome to my website. This static page is served by Caddy.</p>    </main>    <footer>        <p>© $(date +%Y) <add your name here></p>    </footer></body></html>
```

5\. Now, execute one of the commands below to `restart` the `Caddy` server and apply your configuration changes.

If successful, both commands do not produce output to the terminal, but you will verify the changes in the following step.

```bash
# Restart the Caddy service using systemctlsudo systemctl restart caddy# Reload the Caddy configuration without stopping the servicecaddy reload
```

6\. Ultimately, visit your domain name on your browser, and you will see the homepage you created, as shown below.

![Verifying the domain is accessible via a web browser ](https://adamtheautomator.com/wp-content/uploads/2024/04/image-7.png)

Verifying the domain is accessible via a web browser

Notice that your domain is also secure, thanks to Caddy!

Caddy automatically manages SSL/TLS certificates for your domains using Let’s Encrypt. This feature ensures all traffic proxied through Caddy is encrypted, enhancing security and privacy.

![Verifying the domain is secure](https://adamtheautomator.com/wp-content/uploads/2024/04/image-6.png)

Verifying the domain is secure

## Transforming Caddy as a Reverse Proxy

You have seen how Caddy serves a static HTML file, but Caddy is beyond a mere web server. Imagine having multiple services running on different ports or servers—managing them individually becomes a hassle.

With Caddy’s reverse proxy capabilities, you can streamline your setup, consolidate your services under one domain, and ensure they all benefit from Caddy’s automatic HTTPS encryption. These services could be a web application in Flask, Node.js, or any other framework.

To transform Caddy as a reverse proxy, carry out the following:

1\. Create a file called `app.py` and add the following code snippets that sets up a simple Flask application that responds with `Hello` when accessed at the root URL (`/`).

This application also provides the flexibility to specify the port number via the `FLASK_PORT` environment variable when running the application. The port defaults to `3000` if the variable is not set.

```bash
from flask import Flask# Create an instance of the Flask classapp = Flask(__name__)# Define a route for the root URL ("/") and associated view function@app.route("/")def hello():    # Return the string "Hello" as the response    return "Hello"# Check if the script is being run directlyif __name__ == "__main__":    import os    # Read the value of the FLASK_PORT environment variable    # Convert it to an integer, defaulting to 3000 if not set    port = int(os.environ.get("FLASK_PORT", 3000))    # Start the Flask development server    # Listen on all available network interfaces (0.0.0.0) on the specified port    app.run(host='0.0.0.0', port=port)
```

2\. Next, run the following command to set the `FLASK_PORT` environment variable to specify the port number `4000`, and run the Flask application.

```bash
export FLASK_PORT=4000python3 app.py
```

![Running the Flask application](https://adamtheautomator.com/wp-content/uploads/2024/04/image-14.png)

Running the Flask application

3\. Now, visit your server address followed by port 4000 (i.e., 172.x.x.x:4000) to access your Flask application.

![Accessing the Flask application](https://adamtheautomator.com/wp-content/uploads/2024/04/image-13.png)

Accessing the Flask application

4\. Open the _/etc/caddy/Caddyfile_ with your editor and add the following line to include a reverse proxy directive that points to your Flask application.

```python
reverse_proxy / <server-ip>:4000
```

![Adding a reverse proxy configuration](https://adamtheautomator.com/wp-content/uploads/2024/04/image-12.png)

Adding a reverse proxy configuration

5\. Now, `reload` Caddy’s configuration so the changes can take effect and run the flask application again.

```python
sudo systemctl reload caddypython3 app.py
```

6\. Finally, visit your domain (i.e., _**mercyio.xyz**_), and you will be served the **Hello** response from your Flask application securely over HTTPS.

![Accessing the Flask application ](https://adamtheautomator.com/wp-content/uploads/2024/04/image-11.png)

Accessing the Flask application

You will also see the following **GET** request on your terminal.

![Viewing GET requests in Flask](https://adamtheautomator.com/wp-content/uploads/2024/04/image-10.png)

Viewing GET requests in Flask

## Conclusion

You have just unlocked the door to a new level of web deployment efficiency with the Caddy web server. From installing the web server to maneuvering it into a reverse proxy powerhouse, you have covered some solid ground. But guess what? What you have witnessed in this tutorial is merely the beginning.

Now that you have learned the basics that make Caddy an excellent choice for modern web deployments, it is time to level up. Take a deeper dive into Caddy’s documentation and unearth the hidden gems of its feature set.

How about running [Caddy in a Docker](https://www.docker.com/blog/deploying-web-applications-quicker-and-easier-with-caddy-2/) container? Or perhaps further automate your deployment workflows by integrating [Caddy configurations and reloads into your CI/CD pipelines](https://muetsch.io/simple-continuous-docker-deployments-with-caddy.html)?

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fcaddy-web-server%2F&text=Automating%20Site%20Deployments%20with%20Caddy%20Web%20Server)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fcaddy-web-server%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fcaddy-web-server%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2022/03/How-to-Setup-Ngrok-for-Local-Application-Development.jpg)

### [How to Setup Ngrok for Local Application Development](/ngrok/)

Learn how to test your website locally by setting up ngrok on your system for local application development in this step-by-step tutorial!

![](https://adamtheautomator.com/wp-content/uploads/2022/02/How-to-Set-Up-NGINX-on-a-Mac-for-Testing.jpg)

### [How to Set Up NGINX on Mac for Testing](/nginx-on-mac/)

Learn how to set up NGINX on a Mac for testing your website without building a separate server or VM in this step-by-step tutorial!

![](https://adamtheautomator.com/wp-content/uploads/2026/08/featured_image-6.webp)

### [Automate Terraform with Azure DevOps](/automate-terraform-azure-devops/)

Automate Terraform with Azure DevOps Pipelines: structure a multi-environment repo, store remote state in Azure Storage with locking, and deploy through

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
