Оформление оффлайн-страницы сайта
This commit is contained in:
@@ -11,6 +11,25 @@
|
||||
#
|
||||
# SSE (/api/events): отдельный handle БЕЗ encode и с flush_interval -1 — иначе сжатие/
|
||||
# буферизация задержат поток событий (реал-тайм перестанет работать).
|
||||
#
|
||||
# Туннель лёг (апстрим недоступен) → reverse_proxy отдаёт 502/503/504, и сниппет
|
||||
# (offline) подменяет ответ на свою страницу-заглушку (/etc/caddy/maintenance/maintenance.html),
|
||||
# вместо «зависшей загрузки» SPA. Файл заглушки — deploy/vps/maintenance.html.
|
||||
|
||||
# Заглушка «сайт недоступен» при недоступности апстрима. Импортируется в каждый сайт.
|
||||
(offline) {
|
||||
handle_errors {
|
||||
@down expression `{http.error.status_code} in [502, 503, 504]`
|
||||
handle @down {
|
||||
root * /etc/caddy/maintenance
|
||||
rewrite * /maintenance.html
|
||||
header Cache-Control "no-store"
|
||||
file_server {
|
||||
status 503
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forbiddenstars.ru {
|
||||
tls /etc/caddy/certs/forbiddenstars.ru/fullchain.pem /etc/caddy/certs/forbiddenstars.ru/privkey.pem
|
||||
@@ -24,6 +43,7 @@ forbiddenstars.ru {
|
||||
encode zstd gzip
|
||||
reverse_proxy 127.0.0.1:9000
|
||||
}
|
||||
import offline
|
||||
}
|
||||
|
||||
forbidden-stars.ru {
|
||||
@@ -38,4 +58,5 @@ forbidden-stars.ru {
|
||||
encode zstd gzip
|
||||
reverse_proxy 127.0.0.1:9001
|
||||
}
|
||||
import offline
|
||||
}
|
||||
|
||||
+13
-3
@@ -85,16 +85,26 @@ rm -rf /root/certs-tmp
|
||||
> как «промежуточную» часть. Если дал один файл, где leaf и chain уже вместе, — это и есть
|
||||
> `fullchain.pem` (склейка не нужна).
|
||||
|
||||
## 6. Caddyfile
|
||||
Скопируй `deploy/vps/Caddyfile` из репозитория в `/etc/caddy/Caddyfile`, затем:
|
||||
## 6. Caddyfile + страница-заглушка
|
||||
Скопируй `deploy/vps/Caddyfile` из репозитория в `/etc/caddy/Caddyfile` и положи страницу
|
||||
«сайт недоступен» (показывается, когда туннель к хосту лежит — вместо зависшей «Загрузки» SPA):
|
||||
```bash
|
||||
mkdir -p /etc/caddy/maintenance
|
||||
# с локальной машины:
|
||||
scp deploy/vps/maintenance.html root@186.246.51.17:/etc/caddy/maintenance/maintenance.html
|
||||
# на VPS:
|
||||
caddy validate --config /etc/caddy/Caddyfile
|
||||
systemctl reload caddy
|
||||
```
|
||||
> Заглушка живёт в сниппете `(offline)` Caddyfile: при ответе апстрима 502/503/504
|
||||
> Caddy отдаёт `/etc/caddy/maintenance/maintenance.html` со статусом 503 и `Cache-Control: no-store`.
|
||||
> Правки текста/вида — в `deploy/vps/maintenance.html`, затем повтори `scp` (reload Caddy не нужен,
|
||||
> файл читается на каждый запрос).
|
||||
|
||||
## 7. Проверка
|
||||
1. Подними туннель прода на Pi (см. `deploy/pi/README.md`) и/или dev/test на ПК (`run.ps1` при `LOCAL_PUBLIC=vps`).
|
||||
2. Открой `https://forbiddenstars.ru` и `https://forbidden-stars.ru`.
|
||||
3. Пока соответствующий туннель не поднят — Caddy отдаёт `502`, это ожидаемо.
|
||||
3. Пока соответствующий туннель не поднят — Caddy отдаёт страницу-заглушку «Технические шоколадки»
|
||||
(HTTP 503), это ожидаемо.
|
||||
|
||||
Логи Caddy: `journalctl -u caddy -f`.
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="robots" content="noindex" />
|
||||
<!-- Сама перепроверяется: когда хост вернётся, страница перезагрузится и пустит в приложение. -->
|
||||
<meta http-equiv="refresh" content="20" />
|
||||
<title>Сайт недоступен — Forbidden Stars</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #0f1115;
|
||||
--surface: #171a21;
|
||||
--border: #2a2f3a;
|
||||
--text: #e8eaed;
|
||||
--text-muted: #9aa0aa;
|
||||
--accent: #e0533d;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html, body { height: 100%; margin: 0; }
|
||||
body {
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
}
|
||||
.card {
|
||||
max-width: 420px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 32px 24px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.emoji { font-size: 56px; line-height: 1; margin-bottom: 14px; }
|
||||
h1 { font-size: 22px; margin: 0 0 10px; }
|
||||
p { color: var(--text-muted); font-size: 15px; line-height: 1.5; margin: 0 0 18px; }
|
||||
.hint { font-size: 13px; color: var(--text-muted); }
|
||||
.dot {
|
||||
display: inline-block;
|
||||
width: 8px; height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--accent);
|
||||
margin-right: 6px;
|
||||
animation: pulse 1.2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="emoji">🍫</div>
|
||||
<h1>Технические шоколадки</h1>
|
||||
<p>Сайт временно недоступен — мы уже чиним. Загляните через минутку.</p>
|
||||
<div class="hint"><span class="dot"></span>Страница обновится сама, как только всё заработает</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user