Как же меня бесят статьи в духе “Как всего за 139 рублей в месяц развернуть свой сайт-визитку на vps”. Какие 139 рублей за сайт-визитку, совсем уже стыд потеряли?!

В этой статье я вам пошагово расскажу и покажу как бесплатно разместить и вести ваш личный сайт(блог, cv, wiki). Вам даже отдельный домен не нужен (всё будет “из коробки”), хотя в последнем шаге мы и его прикрутим. От вас нужны будут базовые знания git и просто уметь работать с markdown.

Краткий план наш будет такой: создаем специальную репку, ставим локально генератор статических сайтов и генерим странички, немного магии github actions и профит! В основе всего будет GitHub Pages - бесплатный хостинг статических сайтов, который позволяет автоматически публиковать сайт из репозитория GitHub.

Я буду поднимать персональный блог с CV. И я хочу чтобы мой сайт был доступен по красивому адресу https://itcaat.github.io. Тут надо понимать, что занять вы можете адрес только с именем вашего аккаунта, т.е. your_account_name.github.io.

Шаг 1. Создание и настройка репозитория

Создаем новый репозиторий c именем itcaat.github.io. Важно чтобы он имел именно формат: ACCOUNT_NAME.github.io, чтобы хост itcaat.github.io смотрел именно на этот репозиторий. Далее выставляем в настройках репозитория Settings->Pages->Source=Github Actions. Больше никакие настройки не трогаем. На данном этапе у нас будет просто пустой репозиторий без файлов и бранчей.

Image alt
Берем результат из actions, а не из ветки

Шаг 2. Создание базовой структуры

Ставим генератор статических сайтов hugo и создаем базовую структуру.

# https://gohugo.io/installation/ - здесь можете выбрать под свою OS
brew install hugo

# Создаем новый сайт
hugo new site itcaat.github.io

Давайте сразу добавим эти файлы в созданный репозиторий и зальем их. Так нам будет проще видеть историю изменений. Заранее создадим .gitignore.

cd itcaat.github.io

cat <<EOF >.gitignore
public
EOF

git init
git add .
git commit -m "mvp"
git branch -M main
git remote add origin git@github.com:itcaat/itcaat.github.io.git
git push -u origin main

Шаг 3. Подключение темы hugo

Теперь заглянем в магазин тем https://themes.gohugo.io и выберем ту тему что вам подходит. Мне нравится минимализм, поэтому я остановился на https://github.com/athul/archie. Подключим репозиторий с темой как сабмодуль.

git submodule add https://github.com/athul/archie.git themes/archie

Шаг 4. Перенос настроек из темы

Почти все темы содержат пример сайта со всеми необходимыми параметрами для корректной работы темы. Давайте перенесем контент и настройки из exampleSite в корень нашего репозитория.

cp -R themes/archie/exampleSite/* ./

Обычно в exampleSite основные настройки лежат в config.toml. Поэтому нам надо переложить их в hugo.toml чтобы генератор всё подхватил.

mv ./config.toml ./hugo.toml
git add . && git commit -m "added theme athul archie" && git push

Поздравлю, мы уже можем сгенерировать сайт локально и посмотреть что у мы имеем на данный момент. Тут важно понимать что сервер поднимается просто для локального тестирования - он просто собирает всё воедино из css, тем и md-файлов.

hugo server --buildDrafts

# Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
# Web Server is available at http://localhost:1313/ (bind address 127.0.0.1) 
# Press Ctrl+C to stop
Image alt
Пробный запуск

Открываем http://localhost:1313/ и смотрим что всё корректно работает. “Но тут же чужие посты и контакты!” скажете вы. Cейчас это поправим. За то что мы видим на сайте отвечают файлы внутри content и файл конфигурации hugo.toml. Я не хочу подробно тут останавливаться на hugo.toml - там всё интуитивно понятно. У меня будет примерно будет так:

baseURL = "https://itcaat.github.io"
title = "ItCaat personal blog and CV"
....
[[params.social]]
name = "GitHub"
icon = "github"
url = "https://github.com/itcaat"
[[params.social]]
name = "Twitter"
icon = "twitter"
url = "https://x.com/itcaat"
....

Шаг 5. Наполняем сайт

Тут надо понимать две простые вещи: всё содержимое вашего сайта находится в каталоге content и всё содержимое это обычные md-файлы из которых в дальнейшем генерируется сайт. Мы можем отредактировать, создать и удалить текущие посты как нам нравится. Ну и отредактировать about.md. Новые посты рекомендуется создавать через команду hugo new это позволит создать draft пост с необходимыми полями. Когда пост будет финально готов - то просто удалите draft: true, а также можно дополить description и tags. Но в целом можно и просто вручную создавать файлы.

hugo new posts/kak-kakat.md
Image alt
Пример первого поста в VSCode

Мы подошли к финалу - публикация нашего сайта. Давайте запустим его, проверим что нам всё нравится и зальем финальные правки.

hugo server --buildDrafts
git add . && git commit -m "ready for release" && git push
Image alt
Пример отображения поста локально

Про структуру и картинки

На самом деле не обязательно хранить ваши md файлы в content/posts - можно делать каталоги с именем поста и внутри делать index.md.

alt text
Пример организации структуры

Это довольно удобно, ведь часто мы оформляем свои посты с картинками и будет классно хранить картинки прямо рядом с текстом.

Шаг 6. Публикация

Доверим всю работу по публикации github actions. Для этого просто закинем в .github/workflows/hugo.yml содержимое ниже и commit push. Данный файл сделает всю грязную работу и опубликует наш сайт.

# .github/workflows/hugo.yml
name: Deploy Hugo site to Pages

on:
  # Runs on pushes targeting the default branch
  push:
    branches: ["main"]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

# Default to bash
defaults:
  run:
    shell: bash

jobs:
  # Build job
  build:
    runs-on: ubuntu-latest
    env:
      HUGO_VERSION: 0.145.0
    steps:
      - name: Install Hugo CLI
        run: |
          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
          && sudo dpkg -i ${{ runner.temp }}/hugo.deb
      - name: Install Dart Sass
        run: sudo snap install dart-sass
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5
      - name: Install Node.js dependencies
        run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
      - name: Build with Hugo
        env:
          HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache
          HUGO_ENVIRONMENT: production
        run: |
          hugo \
            --minify \
            --baseURL "${{ steps.pages.outputs.base_url }}/"
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./public

  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Заливаем правки по github actions и дожидаемся публикации нашего сайта. Обратите внимание на env переменную HUGO_VERSION: 0.145.0. Посмотрите локальную версию с помощью команды hugo version и пропишите такую же чтобы не было различий. Заливаем правки.

git add . && git commit -m "github actions" && git push
Image alt
Сборка статики и публикация сайта

Поздравляю, у нас полностью бесплатный, с версионированием, без бекендов и баз данных сайт https://itcaat.github.io. Для тех кому лень разбираться в деталях и вы хотите такой же сайт в таком же исполнении - просто форкайте репу https://github.com/itcaat/itcaat.github.io и наполняйте своим контентом.

Image alt
Сайт собран и запущен на github pages

В принципе этого уже будет достаточно и всё будет работать на бесплатных инструментах. Но если у вас лишние пара сотен рублей и вы хотите подключить свой красивый домен, то надо сделать последний шаг.

Шаг 7. Собственный домен

Давайте прикрутим собственный домен к нашему сайту. Для этого:

1. Нужно прописать A-записи на сервера, которые есть в официальной документации github.

alt text
Пример настройки A записей

2. Выставить настройку Custom domain в Pages(обязательно выставьте Enforce HTTPS чтобы получить сертификат).

Процесс валидации довольно быстрый, но в некоторых случаях может занимать какое то время. После проверки ваш сайт будет доступен по указанному вами домену.

А на этом у меня всё - всем спасибо и хороших выходных.

Комментарии (18)


  1. MountainGoat
    24.05.2025 09:01

    Как говорил один советский иллюзионист, показывая опустевшую коробку: "Только что было - только что нет!"


  1. Nill-Ringil
    24.05.2025 09:01

    Предлагаю следующей статьей написать про Cloudflare Pages для тех же целей. С тем же HugoCMS у него интеграция из коробки, как и с десятком других cms генерящих статичные сайты. Главный плюс CF в том, что он раздает это все со своих CDN-серверов, то есть каждый посетитель будет получать с ближайшего к нему. У самого визитка так сделана(ссылку давать в комменте не буду, что бы не выглядело рекламой)


  1. CoolCmd
    24.05.2025 09:01

    Доверим всю работу по публикации github actions. Для этого просто закинем в .github/workflows/hugo.yml содержимое ниже и commit push. Данный файл сделает всю грязную работу и опубликует наш сайт.

    можно объяснить в двух словах, зачем нужны github actions, что за грязную работу они делают? с hugo я не работал.


    1. itcaat Автор
      24.05.2025 09:01

      После пуша github actions пнет hugo чтобы тот из md файлов собрал вам статичный сайт, который будет содержать связанные html страницы, картинки, js и тд. Те по сути готовый статичный сайт. И далее actions опубликует его в pages


      1. CoolCmd
        24.05.2025 09:01

        как я понял из статьи, hugo уже стоит на компе и собирает сайт для предварительного просмотра. почему не собрать им же окончательную версию, зачем поручать это гитхабу?


        1. itcaat Автор
          24.05.2025 09:01

          Примерно по той же причине почему мы не собираем локально программы и не выкладываем их руками.

          Но вы можете делать так как вам нравится и все выкладывать руками. Я предпочитаю вариант когда все собралось и выложилось, а вариант локального запуска оставить для отладки


        1. 13werwolf13
          24.05.2025 09:01

          1) потому что так принято - да звучит странно, но это так
          2) потому что в дальнейшем вообще не обязательно иметь установленный hugo, достаточно редактировать md файлы любым текстовым редактором хоть на телефоне
          3) потому что человеческий фактор - если hugo на этапе сборки вернёт отличный от нуля код возврата то CI не сделает релиз, а замыленный глаз или кривонаписанная автоматизация могут это и упустить


          1. Nill-Ringil
            24.05.2025 09:01

            в дальнейшем вообще не обязательно иметь установленный hugo, достаточно редактировать md файлы любым текстовым редактором хоть на телефоне

            Я на визитке и на блоге порой вообще в браузере лезу в гитхаб или гитлаб(один там, другой там) и правлю файлы, то есть локально не то что hugo может не быть, но и md-файлов


        1. AlexJameson
          24.05.2025 09:01

          Один из бонусов в том, что вы можете внезапно понять, что в статье, которую вы опубликовали в конце рабочего дня, есть битая ссылка или досадная опечатка, и вы можете зайти с телефона и поправить что-то прямо в исходниках на гитхабе. Сайт после этого сразу пересоберется без дополнительных действий.


  1. Jijiki
    24.05.2025 09:01

    спасибо, видел да на гитхабе делают страницу, теперь понял что это)


    1. itcaat Автор
      24.05.2025 09:01

      Рад, что удалось разобраться


  1. fosihas
    24.05.2025 09:01

    Человек платит:

    Какие 139 рублей за сайт-визитку, совсем уже стыд потеряли?!

    Чтобы никогда заниматься вот этим

    2. Выставить настройку Custom domain в Pages(обязательно выставьте Enforce HTTPS чтобы получить сертификат).

    ps:
    сделайте сервис за "адекватную" цену. А мы разберем почему она "неправильная"


    1. itcaat Автор
      24.05.2025 09:01

      Я не очень понял, Вас напугало выставление галочки? Или вы решили что за 139 у вас будет штат инженеров, которые решат все вопросики, включая настройку сертификатов. Поищите статьи которые рассказывают как настроить сайты-визитки на их vps серваках и вы очень удивитесь насколько там все сложнее описано. Но мы то знаем зачем они гонят туда народ ;)


      1. fosihas
        24.05.2025 09:01

        Я о том что у разных человеков, разный набор знаний. И можно не знать, а купить уже готовый продукт.

        А вопрос цены, это другая категория


        1. Mr_Boshi
          24.05.2025 09:01

          За такие деньги обычно продают самый базовый VPS без домена, без сертификатов, даже без панелей, одна голая консоль. Не очень понятно чем этот готовый продукт лучше (или требует принципиально других знаний), чем тоже готовый вариант из статьи.


  1. Sazonov
    24.05.2025 09:01

    А ещё можно netlify - эффект тот же, но настройка намного проще


  1. souls_arch
    24.05.2025 09:01

    Помимо других мест для статики есть еще несколько ресурсов, где можно и динамику с бэкендом, бд, кафкой, бассейном, преферансом и кокотками. Просто про все, в том числе про хостинг единственного персонального для аккаунта на гитхабе, уже не раз писали.


  1. runaway
    24.05.2025 09:01

    Простите.