Коротко. Этот сайт собран на Astro, код лежит в GitHub, а на хостинг Timeweb он выкладывается сам — через 30–60 секунд после каждого изменения. Настроить всё удалось за вечер, но по пути пришлось решить три проблемы: IPv6, заглушку хостинга и отсутствие защищённого FTP на тестовом периоде.
Почему такая схема
Нам нужен был сайт со статьями и калькулятором — без базы данных и без WordPress. Поэтому выбрали статический сайт: генератор Astro превращает статьи в обычные HTML-файлы, которые можно положить на любой хостинг.
- Код и история изменений — в GitHub.
- Публикация — GitHub Actions: после каждого изменения он собирает сайт и загружает файлы на хостинг.
- Хостинг — российский. Сначала думали о Cloudflare Pages, но выбрали хостинг с серверами в России: наша аудитория в России, а данные посетителей по закону должны храниться в российских базах данных.
Что делали
- Зарегистрировались в Timeweb и получили 10 дней бесплатного теста. Сразу выдали технический адрес вида
логин.tw1.ru— сайт можно проверять ещё без домена. - Создали репозиторий в GitHub и тестовую страницу.
- Записали данные FTP в секреты GitHub: сервер, логин и пароль. Пароль от FTP совпадает с паролем от панели Timeweb, поэтому в коде и в переписке его нет — только в зашифрованных секретах.
- Настроили 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.