| January 6, 2023
Hugo позволяет легко и быстро получить красивый статический веб-сайт. Однако, веб-сайт бесполезен, если его никто не видит.
В этой статье, Я расскажу о том, как бесплатно (!) разместить свой собственный статический веб-сайт в российском сервисе - Яндекс Облако. И не просто разместить вручную, Я расскажу о том, как настроить автоматический CD пайплайн в GitHub, дабы каждое изменение, сделанное в проекте сайта, автоматически развёртывалось в сети Интернет.
Инструкции в статье, прежде всего, относятся к веб-сайтам, созданным с помощью Hugo. Однако, работа с Яндекс Облаком отношения к Hugo - не имеет. Вы вольны разместить в Облаке статический веб-сайт, созданный абсолютно любым способом.
Прежде, чем начать
Для выполнения инструкции, нам потребуются:
- свой собственный Hugo сайт
- учётная запись в GitHub и приватный репозиторий, в котором этот сайт хранится
- и учётная запись в сервисе Яндекс Облако
О создании собственного сайта на Hugo, Я уже рассказывал тут, а так же, создал целый образовательный курс.
Учётную запись в GitHub можно завести на сайте проекта. Размещение сайта в приватном репозитории не является частью этой статьи, но Вы без проблем сможете это сделать, следуя инструкциям самого GitHub’а.
Ну и наконец, завести учётную запись в инфраструктурном сервисе Вы сможете перейдя на сайт Яндекс Облака.
Готовим облака
В Яндекс Облако нас интересует сервис под названием - Object Storage. Это полный аналог Amazon AWS S3. Сервис предназначен для хранения статических данных малых и больших объёмов, с разным уровнем доступа к ним. Сервис позволяет конфигурировать доступ к данным, в том числе, позволяет открывать доступ к содержимому хранилища, под сгенерированным доменным именем. Именно это нас и интересует.
Прежде чем наш веб-сайт станет доступен нашим клиентам, его нужно где-то в Интернете разместить. Для этого мы воспользуемся бакетами Object Storage.
Создание бакета
Что такое бакет? Бакет - это способ организации хранения данных в Object Storage сервисе. Другими словами, это единое адресное пространство или аналог диска в файловой системе, который создаётся для проекта.
Каждый бакет имеет имя, а так же ряд других настроек.
Если Вы не хотите читать справку по каждой из настроек - ничего страшного. Можно создать бакет как есть. Достаточно, отметить Доступ на чтение объектов
, как Публичный.
Остальные настройки по умолчанию отлично подходят для статического веб-сайта.
Единственное, о чём следует сразу же подумать, так это о том, будете ли Вы, в дальнейшем размещать веб-сайт под своим собственным доменным именем. Если да, то имя бакета должно быть полным доменным именем Вашего веб-сайта. Например, на примере Выше, Я подразумеваю, что будущий веб-сайт, размещённый в Яндекс Облаке будет доступен под доменным именем plan.ru
.
В данной статье, мы НЕ будем заниматься настройкой доступа к сайту по произвольному доменному имени. Однако, если для Вас это важно - то требование к названию бакета стоит иметь ввиду.
Публикация сайта вручную
После создания бакета, Вы увидите следующую страницу:
Внимательный читатель обратит внимание на кнопку Загрузить объекты
. С помощью этой кнопки, мы можем загрузить наш веб-сайт в бакет.
Эксперимента ради, Я загружу основной index.html
файл своего веб-сайта.
Готово. Наш сайт (точнее, один его файл) лежит в Яндекс Облаке, и всё, что нам нужно сделать, чтобы к нашему сайту можно было обратиться, это настроить Яндекс Облако, на работу в режиме хостинга статических сайтов. Как это сделать?
Всё предельно просто.
Там же, в Object Storage, в меню, есть пункт Веб-сайт
. Именно там, нужно выставить режим Хостинг
, настроить отображение главной страницы и страницы ошибок и сохранить изменения.
Обратите внимание, там же, Object Storage подсказывает нам, по какому именно адресу будет доступен наш веб-сайт в сети Интернет. Впрочем, уже сейчас, после этих действий, если перейти по указанному в Вашем Object Storage адресу, Вы увидите главную страницу Вашего сайта. Её отображение будет поломано - это нормально.
Последние шаги
Чтобы Ваш веб-сайт нормально отображался, нужно проделать три вещи.
Указать публичный адрес Вашего сайта из Object Storage в качестве baseUrl
в конфигурации Вашего Hugo веб-сайта
Делается это путём добавления следующей настройки в config-файл Вашего Hugo веб-сайта. В моём случае, это будет выглядеть вот так:
baseUrl: 'http://plan.ru.website.yandexcloud.net'
Пересобрать веб-сайт
Хорошей практикой является пересборка сайта вместе с минификацией ресурсов и скриптов. Минификация это процесс упразднения ненужных вещей из сборки, в целях экономии занимаемого пространства и ускорения подгрузки ресурсов.
В Hugo подготовка веб-сайта к использованию в продакшн окружении делается с помощью команды:
hugo --minify
В результате её выполнения, в папке public
Вашего Hugo проекта будет актуальное и готовое к использованию состояние Вашего сайта.
Загрузка файлов веб-сайта в облако
Всё содержимое папки public
необходимо загрузить в бакет Яндекс Облака.
Результат
После всех этих действий, Ваш веб-сайт станет полностью доступен по адресу, указанному в Object Storage.
В случае, если Вам потребуется изменить содержимое веб-сайта, потребуется пересборка сайта и перезагрузка всех его файлов в бакет.
Вручную, делать это не особо радостное занятие, согласитесь? И поэтому, далее, поговорим о автопубликации Вашего сайта.
Автопубликация
Под автопубликацией, Я имею ввиду механизм, который на каждый коммит в репозиторий Вашего проекта, будет выполнять ряд действий за Вас, а именно - сборку наиболее актуальной версии проекта и загрузку всего сайта в Ваш бакет.
В профессиональной разработке, этот подход называется CD или Continious Deployment и он экономит массу времени разработчиков.
Для автопубликации, нам потребуются несколько вещей:
API ключи для клиентских приложений Object Storage
API ключи - это сгенерированные самим Яндекс Облаком токены (проще говоря - специальные строки), посредством которого, клиентские приложения, обращаясь в API Object Storage подтверждают то, что они имеют право работать с бакетами, загружать и удалять данные в них.
Для генерации API ключа, необходимо
- Перейти на страницу Дашборда Яндекс Облака
- Перейти в пункт
Сервисные аккаунты
- Нажать
Создать сервисный аккаунт
В появившемся окне, необходимо задать название сервисного аккаунта. Чтобы не запутаться в будущем с сервисными аккаунтами, Я крайне рекоммендую указывать в названии принадлежность к репозиторию и проекту. Например, если бы у меня был репозиторий под названием plan.ru
на GitHub, то название сервисного аккаунта, стоило бы выставить как github-plan-ru
.
- На странице нового сервисного аккаунта, необходимо нажать
Создать новый ключ
->Создать статический ключ доступа
->Создать
- И наконец, в появившемся окне, Вам будут выданы данные ключа - его идентификатор и секретный ключ. Эти данные нам понадобятся далее, поэтому сохраните их куда-нибудь.
Секреты для GitHub Action’а
Теперь, когда мы сгенерировали новый API-ключ для нашей автопубликации, нам необходимо отдать его нашей клиентскому приложению, которое и будет выполнять сборку и загрузку новых версий нашего веб-сайта. Этим приложением является - GitHub Workflow, который мы создадим в следующем пункте. Для его работы, нам необходимо задать секреты.
Что такое секреты в GitHub? Это приватная информация, которая не может присутствовать явно в коде, в репозитории, но необходима для работы, например, GitHub Action’ов. Для того, чтобы такие чувствительные данные использовать без их разглашения, и существуют секреты.
Нам понадобятся три секрета:
BUCKET
- его значением должно быть полное название бакета, в который наш GitHub Action будет загружать файлы веб-сайта. В моём случае, это будетplan.ru
ACCESS_KEY_ID
- его значением должен стать идентификатор сгенерированного ключа. Ещё точнее - сюда нужно скопировать первое значение формы, изображённой на Рисунке 7.SECRET_ACCESS_KEY
- и наконец, его значением должен стать, как несложно догадаться, секретный ключ Вашего сгенерированного API-ключа. Ещё точнее - сюда нужно скопировать второе значение формы, изображённой на Рисунке 7.
Указанные секреты, можно создать в настройках репозитория на GitHub: Settings
-> Secrets
-> Actions
.
GitHub Workflow
Ну и наконец, заключительный шаг - добавление нового GitHub Workflow’а в Ваш проект.
Для того, чтобы добавить GitHub Workflow с Action’ами, в корне Вашего проекта, необходимо создать файл .github/workflows/yandex-cloud-object-storage.yml
(на самом деле название самого yml файла не имеет никакого значения. Важны путь и содержимое файла):
name: Deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.109.0'
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: nekitcorp/yandex-storage-website-action@v1
with:
accessKeyId: ${{ secrets.ACCESS_KEY_ID }}
secretAccessKey: ${{ secrets.SECRET_ACCESS_KEY }}
bucket: ${{ secrets.BUCKET }}
path: "./public"
clear: true
Этот workflow содержит несколько шагов, и два GitHub Action’ов, которые делают автоматическую публикацию для нас. Давайте разберём особо важные части конфигурации workflow:
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.109.0'
extended: true
- name: Build
run: hugo --minify
Первый шаг - Setup Hugo
отвечает за настройку Hugo в окружении. Грубо говоря, после его работы, в последующих шагах, мы вольны использовать команды Hugo. Второй шаг - Build
, содержит уже знакомую нам команду hugo --minify
. Благодаря этим двум шагам, наш Hugo веб-сайт собирается для работы в продакшн окружении и результат сборки публикуется в папку public
. Всё как обычно.
- name: Deploy
uses: nekitcorp/yandex-storage-website-action@v1
with:
accessKeyId: ${{ secrets.ACCESS_KEY_ID }}
secretAccessKey: ${{ secrets.SECRET_ACCESS_KEY }}
bucket: ${{ secrets.BUCKET }}
path: "./public"
clear: true
Следующий шаг, использует специальный GitHub Action - nekitcorp/yandex-storage-website-action@v1
для загрузки данных Вашего сайта в Яндекс Облако. Если взглянуть на его конфигурацию в пункте with
, можно заметить знакомые названия - наименования секретов указывают на то, значения каких именно секретов и куда будут подставлены. Ну а path: "./public"
указывает action’у содержимое какой конкретно папки будет использовано для загрузки в Object Storage. Последняя опция clear: true
означает на то, что перед загрузкой новой версии сайта в бакет, старая будет полностью вычищена.
Автопубликация в действии
После всех этих действий, автопубликация настроена и будет происходит автоматически после каждого коммита. Если совсем быть точным - после каждого коммита в репозиторий, GitHub будет автоматически стартовать испонение настроенного ранее Workflow.
Если Вы всё настроили верно, то после того, как Вы закоммитили Workflow, первый же следующий коммит должен привести к автопубликации. Увидеть запуск workflow можно на вкладке Actions в GitHub. Перейдя на страницу Action’ов Вы увидите историю запусков Вашего workflow, а так же удобную цветовую индикацию статусов запусков:
Ну и наконец, если последний запуск workflow был завершён успешно, по указанному в Object Storage адресу, Вы сможете найти свой сайт:
Заключение
Статья получилась объёмной, и, возможно даже, для кого-то - сложной. Однако, достаточно потратить один вечер, для того, чтобы настроить автоматическую публикацию сайта в Яндекс Облако, чтобы больше никогда не возвращаться к этому вопросу и заниматься только разработкой сайта.
Список материалов
- 🇬🇧 Документация по командам командной строки Hugo
- 🇬🇧 Документация по GitHub Action’у для загрузки контента в Яндекс Облако