Статические сайты
Как создать статический сайт, загрузить файлы и управлять ими в WebShield.
Статический сайт можно разместить прямо в WebShield — без своего хостинга. Файлы хранятся у нас и раздаются через тот же защитный слой, что и проксируемые сайты: CDN-кеш, WAF, защита от ботов.
Требования
Заголовок раздела «Требования»- Хостинг статических сайтов доступен на тарифе домена. Объем хранилища и максимальный размер файла зависят от тарифа.
- Сайт живёт на основном домене или на любом его поддомене. Заранее заводить запись не нужно; если у имени уже есть
A,AAAAилиCNAME, после снятия сайта она вернётся. - Для имени не должно быть включено проксирование.
Создание сайта
Заголовок раздела «Создание сайта»- Откройте раздел Сайты.
- Нажмите Создать и выберите имя из списка или пункт Новое имя…. Уже проксируемые и занятые имена отмечены и недоступны.
- Сайт создается в статусе Отключен — он не виден посетителям, пока вы не опубликуете его.
Загрузка файлов
Заголовок раздела «Загрузка файлов»Стартовой страницей служит index.html в корне сайта. Загрузить файлы можно несколькими способами:
- Перетаскивание — перетащите файлы или папки в зону загрузки. Структура подкаталогов сохраняется.
- Выбрать файлы / Выбрать папку — загрузка через диалог выбора. При выборе папки сохраняются относительные пути.
- В конкретную папку — кнопка загрузки на строке папки в списке файлов добавляет выбранные файлы именно в нее.
- ZIP-архив — загрузка архива полностью заменяет текущее содержимое сайта. Остальные способы работают в режиме слияния: новые файлы добавляются, совпадающие пути перезаписываются.
Работа с файлами
Заголовок раздела «Работа с файлами»Файлы отображаются деревом с подкаталогами. Для папок показывается суммарный размер содержимого.
- Скачивание: файл скачивается как есть; папка или весь сайт (кнопка ZIP в шапке списка) — ZIP-архивом.
- Просмотр: текстовые файлы (HTML, CSS, JS, JSON и другие, до 512 КБ) открываются в окне просмотра.
- Удаление: отметьте файлы и папки и нажмите Удалить выбранное. Папка удаляется вместе с содержимым. Удалить один элемент можно кнопкой в его строке.
- Обновление файла: загрузите файл по тому же пути — он перезапишет старый.
Публикация
Заголовок раздела «Публикация»Загруженные файлы попадают в черновик (рабочую область) — её показывает файловый менеджер. Посетители видят последнюю опубликованную версию, а не черновик.
Кнопка Опубликовать:
- Делает неизменяемый снимок черновика как новой версии (атомарно: посетители не увидят полуобновлённый сайт).
- Переключает DNS-запись хоста на инфраструктуру WebShield. Исходная запись сохраняется и будет восстановлена при отключении сайта.
- Выпускает TLS-сертификат (если включен HTTPS и домен делегирован).
- Делает новую версию доступной посетителям.
Отключить снимает сайт с публикации и восстанавливает исходную DNS-запись; файлы сохраняются. Удаление сайта удаляет файлы и полностью освобождает имя хоста.
Кеширование
Заголовок раздела «Кеширование»Контент кешируется на edge-узлах. Каждая публикация — это новая версия, поэтому кеш сбрасывается автоматически: после публикации посетители сразу получают новый контент, без ручной очистки. Если вы заменили файлы в черновике и хотите, чтобы их увидели посетители, нажмите Опубликовать.
Настройки
Заголовок раздела «Настройки»- Генератор сайта — выбор пресета (Hugo, Jekyll, Astro, Gatsby, Next.js export, SPA, обычный HTML). Пресет задаёт значения остальных настроек; их можно поправить вручную.
- Чистые URL — как «красивые» адреса разрешаются в файлы под специфику генератора:
- Индекс каталога —
/about→/about/index.html(Hugo, Jekyll, Astro, Eleventy, Gatsby); - Расширение .html —
/about→/about.html, затем/about/index.html(Next.js export); - Только точный путь — без догадок.
- Индекс каталога —
- Страница 404 — документ для отсутствующих путей (например
404.html), отдаётся со статусом 404. Пусто — отдавать ответ origin как есть. Свою страницу для раздела — например, для русской версии сайта — задаёт правило 404 в_redirects. - Режим SPA — отдавать
index.html(со статусом 200) для неизвестных путей. Включите для одностраничных приложений с client-side маршрутизацией. - Публиковать по HTTPS — выпустить сертификат и отдавать сайт по HTTPS с перенаправлением с HTTP.
- Защита от ботов —
Отключено,Проверка браузераилиПроверка капчей. Работает так же, как для проксируемых сайтов.
Изменения настроек опубликованного сайта применяются автоматически.
Переадресации
Заголовок раздела «Переадресации»Переехала страница, сменился генератор, поменялась структура разделов — а старые ссылки уже разошлись по поисковикам и чужим статьям. Бросать их на 404 жалко. Положите в корень сайта файл _redirects:
# старые адреса → новые/old-page /new-page 301/blog/* /posts/:splat 301/docs/:section/ /guide/:section/ 302/go/telegram https://t.me/example
# SPA внутри раздела/app/* /app/index.html 200
# своя страница 404 у каждого языка/ru/* /ru/404.html 404/en/* /en/404.html 404
# с корня — на версию на языке браузера/ /ru/ 302 Language=ru,uk,be/ /en/ 302Одна строка — одно правило: откуда, куда и, по желанию, код. Без кода — 301. Пустые строки и строки с # пропускаются. Формат совпадает с Netlify и Cloudflare Pages, так что готовый файл обычно переезжает без правок.
Правила вступают в силу с публикацией. Сам файл посетителям не отдаётся — открыть его по адресу /_redirects не выйдет. Сколько правил сейчас действует, видно в настройках сайта.
Откуда:
*— хвост адреса целиком, только в конце:/blog/*ловит и/blog, и/blog/2024/hello. В цели он подставляется как:splat.:имя— ровно один сегмент:/docs/:sectionловит/docs/install, но не/docs/install/linux.- Регистр латиницы и хвостовой слеш не важны:
/Old-Page/сработает для правила/old-page. - Query-строка в источнике не поддерживается. Зато в цель она переносится сама:
/old-page?utm=mailуедет на/new-page?utm=mail. Если у цели есть свой?…, остаётся только он.
Куда и с каким кодом:
301,308— постоянный переезд,302,303,307— временный. Цель — путь на этом сайте или полный адресhttps://….200— отдать файл этого сайта под другим адресом, без перенаправления. Срабатывает только тогда, когда по запрошенному адресу файла нет:/app/*не заденет настоящий/app/logo.svg.404— страница «не найдено» для раздела, подробности ниже.- Правила проверяются сверху вниз, выигрывает первое подходящее. Переадресации
3xxсрабатывают раньше раздачи файлов: даже если старая страница ещё лежит на месте, посетитель уедет на новую.
Чего здесь нет — и где это искать:
/* /404.html 404— это Страница 404 в настройках сайта./* /index.html 200— это Режим SPA.- Отправка путей на ваш сервер (
/api/* https://api.example.com/:splat 200) — это API на том же домене. - Условия по стране и cookie не поддерживаются.
Страница 404 для раздела
Заголовок раздела «Страница 404 для раздела»У многоязычного сайта «страница не найдена» тоже должна говорить на языке читателя. Правило с кодом 404 назначает разделу свою страницу:
/ru/* /ru/404.html 404/en/* /en/404/index.html 404Страницу раздела получает любой адрес под /ru/, для которого нет ни файла, ни подходящего правила 200, — со статусом 404, как и положено. Адреса вне разделов получают Страницу 404 из настроек сайта. Разделы проверяются сверху вниз: если /ru/docs/* должен отличаться от /ru/*, ставьте его выше.
- Источник — раздел с
*на конце. Весь сайт (/*) настраивается не здесь, а полем Страница 404. - Цель —
.html-страница этого сайта, без:splatи:имя. Если файла нет в публикации, публикация остановится с ошибкой: битую ссылку на страницу 404 никто бы не заметил. - В Режиме SPA правила 404 не работают — приложение отвечает на любой адрес. Сайт с такими правилами в режим SPA не переключится.
Язык браузера
Заголовок раздела «Язык браузера»Условие Language= отправляет читателя на версию на его языке:
/ /ru/ 302 Language=ru,uk,be/ /en/ 302Язык берётся тот, что стоит в настройках браузера первым. ru подходит и для ru-RU, и для ru-BY; pt-BR — только для бразильского португальского. Если условие не совпало, проверка идёт дальше по списку, поэтому общее правило без условия ставьте ниже.
Здесь нарочно строже, чем у Netlify:
- Только временные коды
302,303,307. Постоянную переадресацию браузер запоминает навсегда, и читатель, однажды пришедший с русским браузером, уже не откроет английскую версию. - Только точный адрес, без
*и:имя: чаще всего это корень/. Правило вида/* → /ru/:splatне пустило бы человека на страницу другого языка даже по прямой ссылке.
Поисковые роботы язык не присылают, поэтому по условию никуда не уходят и видят страницу как есть. Подскажите им языковые версии через hreflang на страницах.
Ошибку в файле мы не проглатываем: публикация останавливается, а в ответе будет номер строки и причина. Сайт при этом продолжает работать на прежней версии. Ограничения: до 2000 правил, из них до 100 с * или :имя, файл — до 128 КБ.
API на том же домене
Заголовок раздела «API на том же домене»Нужна только обработка форм обратной связи? Сервер для неё не обязателен — см. Формы на статическом сайте.
Сайт-генератор редко бывает совсем статичным: форма обратной связи, подписка, поиск — что-то да отправляет запрос. Обычно это решают отдельным доменом api.example.com, а дальше начинаются CORS, preflight-запросы и cookie с SameSite=None.
Проще держать всё на одном имени: страницы отдаём мы, перечисленные пути уходят на ваш сервер.
- Откройте сайт в разделе Сайты и найдите блок API на этом домене.
- В Маршрутах перечислите пути, по одному на строку:
/api/,/form,/feedback. - В Адресе вашего сервера укажите, куда их отправлять:
api.example.comили203.0.113.10, при необходимости с портом. - Сохраните. Всё остальное по-прежнему раздаётся из нашего хранилища.
Что стоит знать:
- Хвостовой слеш значащий.
/apiзахватывает и/apidocs;/api/— только вложенные пути. Корень указать нельзя: сайт целиком на вашем сервере — это режим проксирования, а не статический сайт. - Заголовок
Hostмы передаём как у сайта. Ваш сервер должен отвечать на имя сайта, а не только на своё собственное. - На этих путях не показывается проверка браузера — она по своей природе ломает
fetchи SDK. При этом фильтрация вредоносных запросов, лимиты частоты и блокировки адресов на них работают: WAF никуда не девается. - Адрес сервера должен быть публичным. Приватные и локальные адреса мы не принимаем.
- Если адрес перестал разрешаться, сайт продолжает открываться — отвечать перестают только пути API. Смену IP у вашего сервера мы подхватываем сами, в течение нескольких часов.
- Соединение к вашему серверу идёт по HTTP/1.1; WebSocket на этих путях не поддерживается.
Публикация из CI
Заголовок раздела «Публикация из CI»Сборка и публикация на каждый пуш — это один шаг с CLI. Что нужно подготовить:
- В карточке сайта, в блоке Токены публикации, создайте токен. Он умеет ровно две вещи — залить файлы и опубликовать этот сайт; ни настройки сайта, ни домен, ни другие сайты ему не доступны. Полный токен показывается один раз, отозвать его можно там же.
- Положите токен в секреты репозитория под именем
WS_TOKEN— CLI читает эту переменную сам. - Добавьте в пайплайн два шага: установка CLI и публикация.
GitHub Actions, Gitea и Forgejo
Заголовок раздела «GitHub Actions, Gitea и Forgejo»Синтаксис workflow у всех трёх один и тот же.
name: Deploy siteon: push: branches: [main]
# Если пушей несколько подряд — старые сборки отменяем, публикует последняя.concurrency: group: deploy-site cancel-in-progress: true
jobs: deploy: runs-on: ubuntu-latest env: WS_TOKEN: ${{ secrets.WS_TOKEN }} # токен публикации; CLI берёт его отсюда steps: - uses: actions/checkout@v5 with: fetch-depth: 1 # история для сборки не нужна - run: npm ci && npm run build # ваша сборка → ./dist - name: Установка CLI run: curl -fsSL https://raw.githubusercontent.com/webshieldpro/webshield-cli/main/install.sh | sh - name: Публикация run: ~/.local/bin/webshield sites publish www.example.com --dir ./distGitLab CI
Заголовок раздела «GitLab CI»deploy: image: node:24 rules: - if: $CI_COMMIT_BRANCH == "main" interruptible: true # новый пуш отменяет текущую публикацию script: - npm ci && npm run build # ваша сборка → ./dist - curl -fsSL https://raw.githubusercontent.com/webshieldpro/webshield-cli/main/install.sh | sh - ~/.local/bin/webshield sites publish www.example.com --dir ./distТокен добавьте в Settings → CI/CD → Variables как WS_TOKEN с галочками Masked и Protected: masked не пустит его в лог задания, protected — в сборки чужих ветвей.
Публикация из собственного S3-бакета
Заголовок раздела «Публикация из собственного S3-бакета»Если вы пользуетесь объектным хранилищем, сайт можно опубликовать прямо из одного из своих бакетов — контент не заливается через WebShield. Загрузите собранный сайт в любой свой бакет, в любую папку, любым S3-инструментом (rclone, aws s3, s3cmd, артефакты CI), а затем опубликуйте его оттуда.
-
В личном кабинете: откройте карточку сайта, найдите блок Публикация из S3-бакета, выберите бакет, укажите префикс (папку) и нажмите Опубликовать из бакета.
-
В CLI:
Окно терминала webshield sites publish-from-bucket www.example.com --bucket web --path public/
Содержимое выбранного префикса заменяет сайт и публикуется как новая неизменяемая версия. Лимиты тарифа по размеру проверяются в момент публикации. Исходник остаётся в вашем бакете (тарифицируется как объектное хранилище); частью статик-хостинга становится только опубликованная копия — исходный бакет можно затем удалить, снимок публикации сохранится.