Коротко. Этот сайт собран на Astro, код лежит в GitHub, а на хостинг Timeweb он выкладывается сам — через 30–60 секунд после каждого изменения. Настроить всё удалось за вечер, но по пути пришлось решить три проблемы: IPv6, заглушку хостинга и отсутствие защищённого FTP на тестовом периоде.

Почему такая схема

Нам нужен был сайт со статьями и калькулятором — без базы данных и без WordPress. Поэтому выбрали статический сайт: генератор Astro превращает статьи в обычные HTML-файлы, которые можно положить на любой хостинг.

  • Код и история изменений — в GitHub.
  • Публикация — GitHub Actions: после каждого изменения он собирает сайт и загружает файлы на хостинг.
  • Хостинг — российский. Сначала думали о Cloudflare Pages, но выбрали хостинг с серверами в России: наша аудитория в России, а данные посетителей по закону должны храниться в российских базах данных.

Что делали

  1. Зарегистрировались в Timeweb и получили 10 дней бесплатного теста. Сразу выдали технический адрес вида логин.tw1.ru — сайт можно проверять ещё без домена.
  2. Создали репозиторий в GitHub и тестовую страницу.
  3. Записали данные FTP в секреты GitHub: сервер, логин и пароль. Пароль от FTP совпадает с паролем от панели Timeweb, поэтому в коде и в переписке его нет — только в зашифрованных секретах.
  4. Настроили GitHub Actions: сборка сайта и загрузка папки с готовыми файлами в public_html.

Проблема 1. GitHub не подключается к FTP

Первая публикация упала с ошибкой AggregateError (control socket). Сайт собрался, а на хостинг не загрузился.

Проверили по шагам: порт 21 открыт, логин и пароль верные — обычный FTP-клиент с серверов GitHub входил без ошибок. Оказалось, у сервера Timeweb есть IPv6-адрес, и инструмент загрузки сначала пытается подключиться по нему. А у серверов GitHub IPv6 нет.

Решение: перед загрузкой получаем IPv4-адрес сервера и подключаемся строго по нему.

- name: Получить IPv4-адрес FTP-сервера
  id: secrets
  run: echo "ipv4=$(dig +short A "${{ secrets.FTP_SERVER }}" | tail -n1)" >> "$GITHUB_OUTPUT"

- name: Загрузить сайт
  uses: SamKirkland/FTP-Deploy-Action@v4.3.5
  with:
    server: ${{ steps.secrets.outputs.ipv4 }}
    username: ${{ secrets.FTP_USERNAME }}
    password: ${{ secrets.FTP_PASSWORD }}
    local-dir: ./dist/
    server-dir: public_html/

Проблема 2. Вместо сайта — заглушка хостинга

Файлы загрузились, но по адресу открывалась страница «Ваш аккаунт готов к работе!». В public_html изначально лежит файл Timeweb index.htm, и сервер выбирал его раньше нашего index.html.

Решение: удалять ничего не стали — добавили в сайт файл .htaccess с одной строкой:

DirectoryIndex index.html

Проблема 3. Защищённое подключение недоступно

Хотелось загружать файлы по защищённому протоколу, чтобы пароль не передавался открытым текстом:

  • FTPS (FTP с шифрованием) сервер отклонил: Requested SSL level failed.
  • SSH/SFTP на тестовом периоде не работал — сервер отвечал This account is currently not available.

Пока оставили обычный FTP. После оплаты тарифа проверим SFTP ещё раз и опишем результат здесь.

Что получилось

  • Публикация занимает 30–60 секунд после каждого изменения.
  • Переезд на другой хостинг — это смена трёх секретов в GitHub и DNS у домена.
  • Сайт быстрый: Lighthouse (тот же движок, что у PageSpeed от Google) даёт скорость 98–100 из 100.

Подробный обзор хостинга — Timeweb: тарифы, панель и опыт подключения.

Читайте также

Частые вопросы

Можно ли публиковать сайт из GitHub на обычный виртуальный хостинг?

Да. GitHub Actions собирает сайт и загружает файлы на хостинг по FTP. Нужен только FTP-доступ — он есть на любом виртуальном хостинге.

Почему GitHub Actions не подключается к FTP Timeweb?

В нашем случае причина была в IPv6: у сервера Timeweb есть IPv6-адрес, а у серверов GitHub IPv6 нет. Помогло подключение строго по IPv4-адресу сервера.

Почему после загрузки сайта открывается заглушка хостинга?

В папке public_html лежит файл хостинга index.htm, и сервер показывает его раньше вашего index.html. Решение — строка DirectoryIndex index.html в файле .htaccess.