Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 78174a8ffc | |||
| ef8a2d27ff |
@@ -8,9 +8,13 @@ server {
|
||||
access_log /var/log/nginx/typograph.access.log;
|
||||
error_log /var/log/nginx/typograph.error.log;
|
||||
|
||||
# SSL-сертификаты
|
||||
# SSL-сертификаты (их добавит Let's Encrypt)
|
||||
|
||||
# Рекомендуемые SSL настройки
|
||||
# Рекомендуемые SSL настройки (
|
||||
|
||||
# --- ЗАЩИТА ОТ БОЛЬШИХ ЗАПРОСОВ ---
|
||||
# Ограничиваем максимальный размер тела запроса (например, 1MB)
|
||||
client_max_body_size 1M;
|
||||
|
||||
# Медиа файлы (загруженные пользователями)
|
||||
location /media/ {
|
||||
|
||||
@@ -35,7 +35,12 @@ http {
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr warn;
|
||||
|
||||
# Настройки сжатия gzip для оптимизации передачи данных (сжимать будет nginx внутри контейнера)
|
||||
# --- ЗАЩИТА ОТ БРУТФОРСА ---
|
||||
# Создаем зону в памяти, где будут храниться IP-адреса (1MB -- 16000 IP).
|
||||
# rate=5r/s - разрешаем 5 запросов в секунду (мягкий лимит).
|
||||
limit_req_zone $binary_remote_addr zone=one:1m rate=5r/s;
|
||||
|
||||
# Настройки сжатия gzip
|
||||
gzip on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
@@ -59,8 +64,22 @@ http {
|
||||
# Убираем токены версии nginx для безопасности
|
||||
server_tokens off;
|
||||
|
||||
# Прямая раздача favicon.ico (для поисковиков и браузеров)
|
||||
# Это быстрее и надежнее, чем редирект через Django
|
||||
# --- ЗАЩИТА ОТ БОЛЬШИХ ЗАПРОСОВ ---
|
||||
# Ограничиваем максимальный размер тела запроса (например, 1MB)
|
||||
client_max_body_size 1M;
|
||||
|
||||
# --- КАСТОМНЫЕ СТРАНИЦЫ ОШИБОК ---
|
||||
error_page 500 /500.html;
|
||||
error_page 502 /502.html;
|
||||
error_page 503 /503.html;
|
||||
error_page 504 /504.html;
|
||||
|
||||
location = /500.html { root /app/public/static_collected; internal; } # файл будет сюда скопирован при сборке образа
|
||||
location = /502.html { root /app/public/static_collected; internal; }
|
||||
location = /503.html { root /app/public/static_collected; internal; }
|
||||
location = /504.html { root /app/public/static_collected; internal; }
|
||||
|
||||
# Прямая раздача favicon.ico
|
||||
location = /favicon.ico {
|
||||
alias /app/public/static_collected/favicon.ico;
|
||||
access_log off;
|
||||
@@ -69,6 +88,10 @@ http {
|
||||
}
|
||||
|
||||
location / {
|
||||
# --- ЗАЩИТА ОТ БРУТФОРСА ---
|
||||
# Применяем зону 'one', разрешаем "всплеск" до 10 запросов.
|
||||
limit_req zone=one burst=10 nodelay;
|
||||
|
||||
proxy_pass http://app_server;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
# Этот файл предназначен для продакшен окружения. Его необходимо скопировать на продакшн-сервер под именем
|
||||
# `docker-compose.yml` в корневой каталог проекта.
|
||||
# Перед запуском убедитесь, что в корне проекта есть файл `.env` с необходимыми переменными окружения.
|
||||
# Также необходимо создать папки `data` и `media` в корне проекта и убедиться, что у пользователя, под которым
|
||||
# запускается docker-контейнер, есть права на запись в эти папки.
|
||||
# Для первого запуска backend-контейнера, возможно, потребуется временно изменить владельца папки `data` на root
|
||||
# и раскомментировать соответствующие строки в секции etpgrf-backend (смотри комментарии в коде ниже).
|
||||
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
@@ -20,6 +28,7 @@ services:
|
||||
# chmod -R 0775 /app/data 2>/dev/null || true &&
|
||||
# python etpgrf_site/manage.py migrate --noinput &&
|
||||
# python etpgrf_site/manage.py collectstatic --noinput &&
|
||||
# cp /app/etpgrf_site/typograph/templates/500.html /app/public/static_collected/50x.html &&
|
||||
# gunicorn --bind 0.0.0.0:8000 --chdir /app/etpgrf_site etpgrf_site.wsgi"
|
||||
#
|
||||
# После первого запуска, на хосте убедиться что файл БД создан. Возвращаем docker-compose.yml (это тот фал который
|
||||
@@ -37,12 +46,12 @@ services:
|
||||
#
|
||||
|
||||
|
||||
# А обычно запускаем в безопасном режиме. Просто миграции, потом collectstatic, потом сервер
|
||||
# А обычно запускаем в безопасном режиме: миграции, потом collectstatic, потом копируем 500.html для Nginx, потом сервер
|
||||
command: >
|
||||
sh -c "python etpgrf_site/manage.py migrate --noinput &&
|
||||
python etpgrf_site/manage.py collectstatic --noinput &&
|
||||
cp /app/etpgrf_site/typograph/templates/500.html /app/public/static_collected/500.html &&
|
||||
gunicorn --bind 0.0.0.0:8000 --chdir /app/etpgrf_site etpgrf_site.wsgi"
|
||||
# command: sh -c "python etpgrf_site/manage.py collectstatic --noinput && gunicorn --bind 0.0.0.0:8000 --chdir /app/etpgrf_site etpgrf_site.wsgi"
|
||||
|
||||
volumes:
|
||||
# База данных (папка data должна быть создана на хосте)
|
||||
|
||||
86
etpgrf_site/typograph/templates/404.html
Normal file
86
etpgrf_site/typograph/templates/404.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ошибка сервера 404 — ETPGRF</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f8f2;
|
||||
color: #1f1f19;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #151111;
|
||||
color: #eceff1;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: lighter;
|
||||
margin-bottom: 1rem;
|
||||
color: #00ccff99;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
margin-left: 28px;
|
||||
opacity: 0.8;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
margin-top: 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: #151111;
|
||||
background-color: transparent;
|
||||
border: #4a4a44 dashed 1px;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
h1 {
|
||||
color: #00ccff99;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: #b0bec5 dashed 1px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="top: 20%; position: relative;">
|
||||
<a href="/">
|
||||
<picture>
|
||||
<source srcset="/static/svg/logo-etpgrf-site-dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<img src="/static/svg/logo-etpgrf-site-light.svg"
|
||||
alt="ETPGRF — единая типографика для веба" width="717" height="151">
|
||||
</picture>
|
||||
</a>
|
||||
<h1>404: Страница не найдена</h1>
|
||||
<p>
|
||||
Запра­шиваемая страница не найдена.<br/>
|
||||
Контент мог быть удалён, перемещён или его тут никогда и не было.<br/>
|
||||
<a class="btn" href="/">На главную</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
86
etpgrf_site/typograph/templates/500.html
Normal file
86
etpgrf_site/typograph/templates/500.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ошибка сервера 500 — ETPGRF</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f8f2;
|
||||
color: #1f1f19;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #151111;
|
||||
color: #eceff1;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: lighter;
|
||||
margin-bottom: 1rem;
|
||||
color: #00ccff99;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
margin-left: 28px;
|
||||
opacity: 0.8;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
margin-top: 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: #151111;
|
||||
background-color: transparent;
|
||||
border: #4a4a44 dashed 1px;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
h1 {
|
||||
color: #00ccff99;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: #b0bec5 dashed 1px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="top: 20%; position: relative;">
|
||||
<a href="/">
|
||||
<picture>
|
||||
<source srcset="/static/svg/logo-etpgrf-site-dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<img src="/static/svg/logo-etpgrf-site-light.svg"
|
||||
alt="ETPGRF — единая типографика для веба" width="717" height="151">
|
||||
</picture>
|
||||
</a>
|
||||
<h1>500: Внутренняя ошибка сервера</h1>
|
||||
<p>
|
||||
Извините, что-то сломалось на сервере или пошло не так.<br/>
|
||||
Пожалуйста, попробуйте позже.<br/>
|
||||
<a class="btn" href="/">На главную</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
86
etpgrf_site/typograph/templates/typograph/403.html
Normal file
86
etpgrf_site/typograph/templates/typograph/403.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ошибка сервера 403 — ETPGRF</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f8f2;
|
||||
color: #1f1f19;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #151111;
|
||||
color: #eceff1;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: lighter;
|
||||
margin-bottom: 1rem;
|
||||
color: #00ccff99;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
margin-left: 28px;
|
||||
opacity: 0.8;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
margin-top: 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: #151111;
|
||||
background-color: transparent;
|
||||
border: #4a4a44 dashed 1px;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
h1 {
|
||||
color: #00ccff99;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: #b0bec5 dashed 1px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="top: 20%; position: relative;">
|
||||
<a href="/">
|
||||
<picture>
|
||||
<source srcset="/static/svg/logo-etpgrf-site-dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<img src="/static/svg/logo-etpgrf-site-light.svg"
|
||||
alt="ETPGRF — единая типографика для веба" width="717" height="151">
|
||||
</picture>
|
||||
</a>
|
||||
<h1>403: Доступ запрещён, необходимо автори­зоваться</h1>
|
||||
<p>
|
||||
Записанная в адресной строке страница требует аутенти­фикации.<br/>
|
||||
Пожалуйста, войдите в систему и повторите попытку.<br/>
|
||||
<a class="btn" href="/">На главную</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -66,14 +66,12 @@
|
||||
<div class="container d-flex justify-content-between align-items-center">
|
||||
<span class="text-muted small nowrap me-2">© Sergei Erjemin, 2025–{% now 'Y' %}.</span>
|
||||
|
||||
<nobr class="text-muted small mx-2"><i class="bi bi-tags me-1" title="Версия библиотеки etpgrf / Версия сайта"></i>v0.1.3 / v0.1.4</nobr>
|
||||
<nobr class="text-muted small mx-2"><i class="bi bi-tags me-1" title="Версия библиотеки etpgrf / Версия сайта"></i>v0.1.3 / v0.1.5</nobr>
|
||||
|
||||
{# Сводная статистика (HTMX) #}
|
||||
<span class="text-muted small ms-2" hx-get="{% url 'stats_summary' %}" hx-trigger="load">
|
||||
...
|
||||
</span>
|
||||
|
||||
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{% load typograph_extras %}
|
||||
<nobr class="ms-3 float-end" title="Скопировано в буфер текстов/символов">
|
||||
{% load typograph_extras %}<nobr class="ms-3 float-end" title="Скопировано в буфер текстов/символов">
|
||||
<i class="bi bi-clipboard-check me-1"></i>{{ copied|humanize_num }} / {{ chars_copied|humanize_num }}
|
||||
</nobr>
|
||||
<nobr class="ms-3 float-end" title="На выход получено символов">
|
||||
@@ -10,7 +9,4 @@
|
||||
</nobr>
|
||||
<nobr class="ms-3 float-end" title="Просмотров">
|
||||
<i class="bi bi-eye me-1"></i>{{ views|humanize_num }}
|
||||
</nobr>
|
||||
|
||||
|
||||
|
||||
</nobr>
|
||||
87
public/static/502.html
Normal file
87
public/static/502.html
Normal file
@@ -0,0 +1,87 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ошибка сервера 502 — ETPGRF</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f8f2;
|
||||
color: #1f1f19;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #151111;
|
||||
color: #eceff1;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: lighter;
|
||||
margin-bottom: 1rem;
|
||||
color: #00ccff99;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
margin-left: 28px;
|
||||
opacity: 0.8;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
margin-top: 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: #151111;
|
||||
background-color: transparent;
|
||||
border: #4a4a44 dashed 1px;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
h1 {
|
||||
color: #00ccff99;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: #b0bec5 dashed 1px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="top: 20%; position: relative;">
|
||||
<a href="/">
|
||||
<picture>
|
||||
<source srcset="/static/svg/logo-etpgrf-site-dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<img src="/static/svg/logo-etpgrf-site-light.svg"
|
||||
alt="ETPGRF — единая типографика для веба" width="717" height="151">
|
||||
</picture>
|
||||
</a>
|
||||
<h1>502: Bad Gateway</h1>
|
||||
<p>
|
||||
Внутренняя ошибка сервера.<br/>
|
||||
Недоступен Gunicorn-сервис, база данных или произошла ошибка при обработке запроса.<br />
|
||||
Пожалуйста, попробуйте позже.<br/>
|
||||
<a class="btn" href="/">На главную</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
86
public/static/503.html
Normal file
86
public/static/503.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ошибка сервера 503 — ETPGRF</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f8f2;
|
||||
color: #1f1f19;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #151111;
|
||||
color: #eceff1;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: lighter;
|
||||
margin-bottom: 1rem;
|
||||
color: #00ccff99;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
margin-left: 28px;
|
||||
opacity: 0.8;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
margin-top: 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: #151111;
|
||||
background-color: transparent;
|
||||
border: #4a4a44 dashed 1px;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
h1 {
|
||||
color: #00ccff99;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: #b0bec5 dashed 1px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="top: 20%; position: relative;">
|
||||
<a href="/">
|
||||
<picture>
|
||||
<source srcset="/static/svg/logo-etpgrf-site-dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<img src="/static/svg/logo-etpgrf-site-light.svg"
|
||||
alt="ETPGRF — единая типографика для веба" width="717" height="151">
|
||||
</picture>
|
||||
</a>
|
||||
<h1>503: Слишком много запросов</h1>
|
||||
<p>
|
||||
Сервер временно перегружен запросами или находится на техническом обслуживании.<br/>
|
||||
Пожалуйста, попробуйте позже.<br/>
|
||||
<a class="btn" href="/">На главную</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
87
public/static/504.html
Normal file
87
public/static/504.html
Normal file
@@ -0,0 +1,87 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ошибка сервера 50x — ETPGRF</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f8f2;
|
||||
color: #1f1f19;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #151111;
|
||||
color: #eceff1;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: lighter;
|
||||
margin-bottom: 1rem;
|
||||
color: #00ccff99;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
margin-left: 28px;
|
||||
opacity: 0.8;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
margin-top: 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: #151111;
|
||||
background-color: transparent;
|
||||
border: #4a4a44 dashed 1px;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
h1 {
|
||||
color: #00ccff99;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: #b0bec5 dashed 1px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="top: 20%; position: relative;">
|
||||
<a href="/">
|
||||
<picture>
|
||||
<source srcset="/static/svg/logo-etpgrf-site-dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<img src="/static/svg/logo-etpgrf-site-light.svg"
|
||||
alt="ETPGRF — единая типографика для веба" width="717" height="151">
|
||||
</picture>
|
||||
</a>
|
||||
<h1>504: Gateway Timeout</h1>
|
||||
<p>
|
||||
Сервер не смог ответить вовремя.<br/>
|
||||
Возможно, текст для типографа слишком большой илия сервер перегружен.<br/>
|
||||
Пожалуйста, попробуйте позже.<br/>
|
||||
<a class="btn" href="#">Обновить страницу</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user