Skip to main content
Caddy is a reverse proxy and web server that terminates TLS and forwards requests to the backend services. The project uses it in production so a single host (e.g. an EC2 instance) can serve api.lokpanchang.com, admin.lokpanchang.com, and docs.lokpanchang.com with HTTPS.

What Caddy is

Caddy is an HTTP server and reverse proxy. It can obtain and renew TLS certificates automatically (e.g. via Let’s Encrypt) and route traffic by hostname to different backends. In this stack it runs as the caddy Docker service and is the only container that exposes ports 80 and 443 to the host.

Why we use it

  • Single entrypoint — One public IP/hostname; Caddy listens on 80/443 and routes by domain.
  • TLS — Caddy handles HTTPS and certificate management so the app services (web, admin-portal, docs) do not need to.
  • Subdomains — Different subdomains map to different containers (web, admin-portal, docs) without extra proxies or manual certificate setup per service.

How subdomains are configured

Configuration is in caddy/Caddyfile at the repo root. The Docker Compose caddy service mounts this file into the container. Each block defines a site and an upstream:
api.lokpanchang.com {
    reverse_proxy web:5050
}

admin.lokpanchang.com {
    reverse_proxy admin-portal:5002
}

docs.lokpanchang.com {
    reverse_proxy docs:5003
}
So:
  • api.lokpanchang.comweb (Flask) on port 5050 (webhooks, API, test routes).
  • admin.lokpanchang.comadmin-portal on port 5002.
  • docs.lokpanchang.comdocs (documentation site) on port 5003.
Caddy resolves web, admin-portal, and docs via the Docker network. DNS for the three hostnames must point to the host where Caddy is running (e.g. EC2 public IP or an Elastic IP). Caddy will then obtain certificates for those names when it receives the first HTTPS request (assuming the host is reachable on 80 for the ACME challenge unless you use DNS challenge).

Production vs development

  • Production: Caddy runs as part of docker compose up; it proxies all three subdomains. Use https://api.lokpanchang.com/webhook in the Meta app and access admin and docs at their respective URLs.
  • Development: You can run the same Compose stack locally; Caddy will only get certificates if the hostnames resolve to your machine and port 80 is reachable from the internet. Alternatively, skip Caddy and hit services directly: http://localhost:5050 (web), http://localhost:5002 (admin), http://localhost:5003 (docs). For local webhook testing with Meta, use Ngrok to expose the web service; Meta’s webhook URL would be the ngrok URL, not Caddy.

Where it’s configured in the repo

  • Config file: caddy/Caddyfile — only file in the repo that defines Caddy’s sites and reverse proxies.
  • Compose: docker-compose.yml — service caddy (image caddy:2, ports 80/443, volumes for Caddyfile and Caddy data/config).