> ## Documentation Index
> Fetch the complete documentation index at: https://docs.maition.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTPS with Caddy

> Run mAItion behind Caddy as a caching SSL-terminating reverse proxy with automatic LetsEncrypt certificates.

mAItion serves all traffic — including static assets — through Open WebUI's Uvicorn server. For production deployments, the optional `compose.caddy.yaml` overlay adds Caddy as a caching reverse proxy that handles automatic TLS certificate issuance via LetsEncrypt and speeds up static asset delivery.

The overlay also starts a dedicated `redis-caddy` sidecar used as Caddy's cache backend: static assets (images, CSS, JS, fonts) are cached for one year with immutable headers, and `manifest.json` is cached for 24 hours. Dynamic chat and API requests bypass the cache entirely and are streamed directly to the browser.

## Requirements

* A public domain with an A/AAAA record pointing to your server
* Ports **80** and **443** open and publicly reachable (required for the LetsEncrypt HTTP-01 challenge). Set `CADDY_HTTP_PORT` / `CADDY_HTTPS_PORT` in `.env` if you need to publish Caddy on different host ports.

## Setup

1. Add the following to your `.env` file:

   ```bash theme={null}
   DOMAIN=maition.example.com
   ACME_EMAIL=admin@example.com
   WEBUI_URL=https://maition.example.com
   ```

   Setting `DOMAIN` to an `http://` URL (e.g. `DOMAIN=http://localhost`) bypasses TLS termination entirely — Caddy will serve the app on plain HTTP. Use this only for local testing.

2. Start the stack with the Caddy overlay by setting `COMPOSE_FILE` so plain `docker compose` picks it up automatically:

   ```bash theme={null}
   export COMPOSE_FILE=compose.yaml:compose.caddy.yaml
   docker compose up -d
   ```

   Or pass the overlay explicitly with `-f`:

   ```bash theme={null}
   docker compose -f compose.yaml -f compose.caddy.yaml up -d
   ```

   Either way, the overlay clears OpenWebUI's host port binding so only Caddy is externally reachable. Caddy will automatically obtain and renew a TLS certificate, and HTTP requests are redirected to HTTPS automatically.

## Troubleshooting

* **Certificate not issued** — check that ports 80 and 443 are reachable from the public internet and your DNS record points to this server. Run `docker compose logs caddy` to see the ACME challenge output.
* **Port 80/443 already in use** — another reverse proxy (Traefik, Nginx, etc.) is likely running on the host. Either stop it, or set `CADDY_HTTP_PORT`/`CADDY_HTTPS_PORT` in `.env` to publish Caddy on different host ports — note that LetsEncrypt's HTTP-01 challenge and normal HTTPS access require the public internet to reach ports 80/443, so this only works if you also forward those public ports to your chosen ones, or you're not relying on public TLS (e.g. local testing).

## Certificate persistence

TLS certificates are stored in the `caddy_data` Docker volume. They survive `docker compose down` but are removed by `docker compose down -v`. Do not use `-v` if you want to preserve your certificates.
