How to Deploy Caddy Server on DigitalOcean App Platform

Yesterday, I covered the deployment of a static website with Caddy on Railway. While Railway is getting quite popular, I know there are several more DigitalOcean enthusiasts out there. So, this time, I'll walk through the deployment of a Caddy Server on DigitalOcean App Platform instead.

What is Caddy Server?

Caddy is a powerful yet simple, Go-based open-source web server. Written in a memory-safe language, it compiles to a single, static binary, making it easy to run Caddy practically anywhere, even in containers. Caddy obtains and renews TLS certificates automatically, staples OCSP responses, and even performs automatic HTTPS rewrites. The modular architecture serves a whole host of use cases from simple static file serving (which we will cover today) to more complex use cases like dynamic reverse proxying and handling Kubernetes ingress.

Image source: caddyserver.com

While Caddy's native config language is JSON, most users prefer the Caddyfile - a simple, human-readable config file which works well for most configurations. Caddy is also dynamically configurable using a RESTful JSON API, making it easy to automate and integrate with your applications.

Deploy Caddy on DigitalOcean App Platform

I'm going to test drive the DigitalOcean App Platform for this tutorial - a self-managed droplet works just fine too, with certificates managed by Caddy. In our case, the App Platform will take care of certificate management (similar to app hosting platforms like Railway and Netlify). If you don't have a DigitalOcean account, sign up here - you’ll receive a $200, 60-day credit as soon as you add a valid payment method to your account.

Log into your GitHub account and fork my caddy-on-digitalocean repository. By default, the site/ directory gets deployed as a static site, but you can change this from the Dockerfile. Replace the default index.html and styles.css files with your own and add other files as necessary.

Set up your team and project in the DigitalOcean console, and click Create App from the Apps workspace. If this is your first time deploying from source code, you'll need to connect your GitHub account and authorize DigitalOcean.

Install & authorize DigitalOcean on GitHub

Once your GitHub account is connected, select the caddy-on-digitalocean repo. If you wish, you can enable Autodeploy so DigitalOcean can track changes to the source code and automatically re-deploy the app upon changes.

Git repository connection

The App Platform automatically selects the Pro plan for the web service - you can click on Edit Plan to downgrade the plan.

Default App Platform pricing plan

The Basic plan, along with the smallest container size, is sufficient for our prototype - for production, you can revisit this configuration. Click Next.

Basic plan, sufficient for a prototype

DigitalOcean sets the HTTP Port to 8080 by default - add a PORT variable with value 80 in the Environment Variables tab to override this setting. DigitalOcean handles certificate management here, and we do not need Caddy to repeat it. Click Save and Next.

Global and local environment variables

Change the assigned App Name and Region if you wish - by default the nearest region is automatically selected for you - and click Next.

App name and region

Review the app configuration and, if all is good, create the resource. Wait a few seconds - once ready, your app will be available at xxx.ondigitalocean.app.

App deployment live
Caddy static website deployed on DigitalOcean

Configure a Custom Domain (Optional)

DigitalOcean services can be exposed to the internet on a custom domain instead of the xxx.ondigitalocean.app subdomain. If you don't already own a domain, head over to Cloudflare Registrar or Namecheap and register a domain first. From the app settings, click on Edit under the domains section, and click Add Domain.

Custom domain

Specify the domain or subdomain name you wish to configure for the service, and select You manage your domain option (assuming you are not using DigitalOcean as your DNS provider).

DNS management

Add a CNAME record for your domain corresponding to the one shown below.

CNAME record

DigitalOcean will automatically trigger a re-deployment on the new domain or subdomain. Once the DNS records propagate, the app will be available on your custom domain!

App re-deployment live on custom domain