Netpulse_SasS/deploy/Caddyfile
byrsapty 6843bd3280
Some checks are pending
CI / web (push) Waiting to run
CI / server (push) Waiting to run
CI / agent (push) Waiting to run
Розгортання на живому сервері: три виправлення, знайдені першим запуском
Образи зібрались із першого разу, але далі знайшлось три речі.

memlock без обмеження для Dragonfly дозволений не всюди: у контейнерній
віртуалізації ядро відмовляє, і контейнер не стартує взагалі. Швидкість
того не варта — обмеження знято.

Caddy нескінченно просив Let's Encrypt видати сертифікат на IP, чого той
не робить, і сайт лишався без TLS. Тепер порожня ACME_EMAIL означає
самопідписаний сертифікат. Плюс default_sni: SNI не містить IP-адрес,
тож без нього рукостискання обривалось «internal error».

У README команда заведення власника не працювала: у образу ENTRYPOINT, і
без --entrypoint ім'я команди йшло аргументом до netpulse-api. Заразом
netpulse-user навчився створювати перший кабінет — свіжа база не має
жодного, а користувач без кабінету нікуди не належить.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 18:07:18 +03:00

83 lines
3.6 KiB
Caddyfile
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Зворотний проксі NetPulse.
#
# Caddy бере на себе сертифікати Let's Encrypt і оновлює їх сам. Це
# знімає з розгортання найчастішу причину нічного дзвінка — прострочений
# сертифікат на системі, яка сама має повідомляти про проблеми.
{
# Яким сертифікатом відповідати, коли клієнт не назвав імені.
#
# SNI не містить IP-адрес: стандарт дозволяє там лише доменні імена,
# тож браузер, який іде на https://93.171.243.247, не каже нічого — і
# Caddy не має за чим обрати сертифікат. Рукостискання обривається
# «internal error», сайт виглядає мертвим.
#
# З доменом ця настройка нічого не міняє: SNI приходить, і збіг
# знаходиться звичайним шляхом.
default_sni {$NETPULSE_DOMAIN}
}
# Одна директива на два випадки.
#
# tls <пошта> — сертифікат від Let's Encrypt на цю адресу;
# tls internal — власний самопідписаний.
#
# Значення приходить із NETPULSE_TLS, яке compose виводить із ACME_EMAIL:
# пошта задана — беремо справжній сертифікат, порожньо — самопідписаний.
#
# Порожнє значення тут не працює: Let's Encrypt не видає сертифікатів на
# публічні IP-адреси, і Caddy вічно повторював би спробу, а сайт лежав
# би без TLS. Перевірено живим розгортанням на голому IP.
# --- інтерфейс і API -------------------------------------------------
{$NETPULSE_DOMAIN} {
tls {$NETPULSE_TLS}
encode zstd gzip
# WebSocket живих оновлень. Окремим блоком, бо йому не можна
# ставити таймаут на відповідь: зʼєднання висить годинами й
# мовчить, поки на мапі нічого не змінюється.
@ws path /api/v1/ws
reverse_proxy @ws api:8080 {
flush_interval -1
}
# API і вшитий у бінарник інтерфейс — за однією адресою, тож
# розділяти їх не потрібно: SPA віддає той самий процес.
reverse_proxy api:8080
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
log {
output stdout
format console
}
}
# --- колектор зондів -------------------------------------------------
#
# Зонди говорять gRPC поверх HTTP/2. Усередині мережі — h2c без TLS:
# сертифікат живе тут, а не в кожному примірнику колектора.
{$NETPULSE_DOMAIN}:9443 {
tls {$NETPULSE_TLS}
reverse_proxy h2c://collector:9443 {
# Потік Control двонаправлений і довгий: агент тримає його
# відкритим, доки живий. Буферизація тут ламає саме те, заради
# чого потік існує — миттєву доставку команд.
flush_interval -1
}
log {
output stdout
format console
}
}