# Caddyfile — единый HTTP/HTTPS public boundary Chatballs (ADR-CHATBALLS-0028 §gateway).
# Подставляется в release bundle и монтируется в контейнер gateway.
#
# Свежая установка не знает своего домена: человек поднимает докер на сервере и
# открывает её по IP. Поэтому здесь нет блоков с зашитым именем хоста — они бы
# заставили Caddy выпускать сертификат и уводить http на https до того, как
# домен вообще появился. Вместо них: :80 отвечает по http на любом адресе, а
# https обслуживает любой хост, который одобрил ask-эндпоинт (домены порталов и
# домен установки, заданный в UI). Сертификаты выписываются по мере надобности,
# без перезапуска шлюза.

{
	# ACME-контакт не задаётся при установке: пока домена нет, нет и выпуска
	# сертификатов. Адрес для уведомлений добавляется вместе с доменом в UI.
	# Caddy admin API не публикуется наружу (default localhost:2019).
	on_demand_tls {
		ask http://backend-platform:8000/api/v1/gateway/help-domain/
	}
	# Установку часто ставят за прокси панели (aaPanel, nginx хоста), который
	# снимает TLS и ходит сюда по http. Его X-Forwarded-Proto/For принимаются
	# только из частных сетей — оттуда, где такой прокси и стоит; клиент из
	# интернета подделать их не может.
	servers {
		trusted_proxies static private_ranges
	}
}

(surfaces) {
	# Host уходит с портом: браузер шлёт Origin с портом (http://ip:8081), и
	# без него CSRF-проверка Django отвергала любой POST на нестандартном
	# порту. X-Forwarded-Proto Caddy ставит сам: {scheme}, а за доверенным
	# прокси — то, что прислал прокси (https, если TLS снят перед нами).

	# Платформенная поверхность живёт на своём домене; пока он не задан,
	# матчер намеренно не совпадает ни с чем.
	@platform host {$CHATBALLS_PLATFORM_DOMAIN:platform.invalid}
	handle @platform {
		reverse_proxy backend-platform:8000 {
			header_up Host {hostport}
			header_up X-Real-IP {client_ip}
			header_up X-Forwarded-For {client_ip}
		}
	}

	# Всё остальное — приложение и публичные порталы: маршрутизация внутри
	# frontend-контейнера.
	handle {
		reverse_proxy frontend:80 {
			header_up Host {hostport}
			header_up X-Real-IP {client_ip}
			header_up X-Forwarded-For {client_ip}
		}
	}
}

# Обычный http на любом адресе: IP сервера, localhost, ещё не подтверждённый
# домен. Редиректа на https здесь нет намеренно — его делает блок ниже, когда
# для хоста реально выписан сертификат.
:80 {
	encode gzip zstd
	import surfaces
}

# Дополнительные сайты из постоянного тома сохраняются при обновлении шлюза.
import /config/sites/*.caddy

# Любой хост, которому ask-эндпоинт разрешил сертификат.
https:// {
	encode gzip zstd
	tls {
		on_demand
	}
	import surfaces
}
