So you have an application. It’s running on your new Hetzner server. You can access it with curl or by visiting your server’s IP address and a specific port like 3000. This is a great first step but it’s not a finished product. You need a domain name and you need HTTPS.
Traditionally this is where you would start reading tutorials about Nginx server blocks or Apache virtual hosts. You would learn about creating configuration files managing SSL certificates with Certbot and setting up cron jobs to renew them. This process works but it is complex and full of small details that are easy to get wrong.
There is a simpler way. For most common use cases all of this complexity is unnecessary. You just want to direct traffic from your domain to your application running on a local port securely. A modern tool called Caddy does this with almost no configuration.
Let’s assume you have a simple web application. It could be a Rails app on port 3000 a Node.js app on port 8080 or a Python app on port 5000. For this example let’s say it’s running on localhost:3000
.
If you run curl http://localhost:3000
on the server you see your app’s HTML. The goal is to make this same application available to the world at https://yourdomain.com
.
Caddy is a web server like Nginx or Apache but with a key difference. It was built with automatic HTTPS as a primary feature. It handles getting and renewing SSL certificates from Let’s Encrypt for you. All you have to do is tell it your domain name and where your application is running.
This removes a huge amount of configuration and maintenance. You get a secure production ready setup by default.
Before you can get an SSL certificate you need to have a domain name pointing to your server’s public IP address. Go to your DNS provider where you registered your domain. You need to create an A record.
DNS changes can take some time to propagate. You can check if it’s working by running dig yourdomain.com +short
on your local machine. Once it returns your server’s IP address you can proceed.
Installing Caddy on a standard Ubuntu server is straightforward. You just need to add its official repository and use apt
to install it. These commands will do the work.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
This installs Caddy and also sets it up to run as a systemd service. This means it can start automatically when your server boots.
Caddy’s configuration file is usually located at /etc/caddy/Caddyfile
. You can edit this file with a text editor like nano
or vim
. The default file has some examples which you can delete.
Replace the entire contents of the file with this.
yourdomain.com {
reverse_proxy localhost:3000
}
That’s it. This is the entire configuration. Make sure to replace yourdomain.com
with your actual domain name and 3000
with the port your application is running on.
This simple block tells Caddy to do three things.
yourdomain.com
.localhost:3000
.Now that Caddy is installed and configured you can start the service. Since the installation package already set up systemd you just need to reload and start it.
sudo systemctl reload caddy
sudo systemctl enable caddy
sudo systemctl start caddy
You can check its status to make sure it started correctly.
sudo systemctl status caddy
If everything is working you should see a green active (running) message. Now you can visit https://yourdomain.com
in your browser. You will see your application served over a secure connection. Caddy handled everything.
You don’t need complex tools for common problems. The simplest solution is often the best one. Think about the last time you got stuck on a seemingly simple infrastructure task and try answering the prompt below.
— Rishi Banerjee
September 2025