Добавил серию Blog 1-5 части. Подправил настройки и внешний вид сайта
This commit is contained in:
@@ -0,0 +1,306 @@
|
||||
---
|
||||
title: "Блог на Hugo в K3s: часть 1 - архитектура и первый запуск"
|
||||
date: 2026-01-03
|
||||
draft: false
|
||||
description: "Как я переехал с Jekyll на Hugo, почему выбрал тему Blowfish и как настроил два окружения с нуля. Начало цикла о том как я строил oakazanin.ru."
|
||||
tags: ["hugo", "blowfish", "gitea", "homelab", "devops"]
|
||||
categories: ["infrastructure"]
|
||||
series: ["Блог на Hugo в K3s"]
|
||||
series_order: 1
|
||||
---
|
||||
|
||||
Предыдущий блог жил на Jekyll. Жил - громко сказано. Скорее существовал, периодически ломаясь при обновлениях и требуя ритуальных танцев с Ruby каждый раз когда я садился за новую статью.
|
||||
|
||||
Однажды я решил что хватит.
|
||||
|
||||
---
|
||||
|
||||
## Почему не Jekyll
|
||||
|
||||
Jekyll - зрелый инструмент с большим сообществом. Но у него есть фундаментальная проблема: он написан на Ruby.
|
||||
|
||||
Звучит невинно. На практике это означает:
|
||||
|
||||
**Версионный ад.** Ruby, Bundler, Gems - у каждого своя версия, и они регулярно конфликтуют друг с другом. Клонируешь репозиторий на новую машину - час уходит на то чтобы собрать рабочее окружение. Обновляешь Jekyll - ломаются плагины. Обновляешь плагины - ломается что-то ещё.
|
||||
|
||||
**Зависимости ради зависимостей.** Простой блог тянет 1000+ gems, половина из которых устаревшая или находится в состоянии "поддерживается постольку-поскольку". Каждый `bundle install` - это лотерея.
|
||||
|
||||
**Лишний мусор.** Jekyll генерирует страницы без ссылок, которые непонятно зачем существуют. Приходится явно прописывать что не генерировать.
|
||||
|
||||
Hugo решает все эти проблемы радикально: это один бинарник на Go. Никаких зависимостей, никаких конфликтов версий, никакого `bundle install`. Скачал - работает. На любой машине, всегда.
|
||||
|
||||
Бинарник весит ~50MB. Собирает сайт из 40+ страниц за полторы секунды. Jekyll на том же контенте думал заметно дольше.
|
||||
|
||||
---
|
||||
|
||||
## Почему Blowfish
|
||||
|
||||
Все просто: понравилась.
|
||||
|
||||
Смотрел темы несколько часов. Blowfish выглядела именно так как я хотел - чисто, без лишнего, с хорошей типографикой. Взял её.
|
||||
|
||||
Ставится как Git submodule - обновляется одной командой, не засоряет репозиторий.
|
||||
|
||||
---
|
||||
|
||||
## Архитектура: два окружения
|
||||
|
||||
У любого нормального инфраструктурного проекта есть тестовый и production контур. Блог - не исключение: обновления Hugo, изменения темы, новые статьи - всё это нужно проверять до того как это увидят читатели.
|
||||
|
||||
```
|
||||
┌────────────────────────────────────┐
|
||||
│ Gitea (внутренний) │
|
||||
│ репозиторий: blog │
|
||||
│ │
|
||||
│ ветка: main ветка: dev │
|
||||
└───────┬────────────────────┬───────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐
|
||||
│ hugo-builder │ │ hugo-builder │
|
||||
│ prod │ │ dev │
|
||||
└───────┬───────┘ └───────┬───────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐
|
||||
│ nginx │ │ nginx-dev │
|
||||
│ blog.ru │ │ dev.blog.ru │
|
||||
│ (публичный) │ │ (Basic Auth) │
|
||||
└───────────────┘ └───────────────┘
|
||||
```
|
||||
|
||||
**Production** (`blog.ru`) - публичный. Ветка `main`.
|
||||
|
||||
**Development** (`dev.blog.ru`) - тестовый контур. Ветка `dev`. Закрыт Basic Auth через Traefik Middleware - без логина и пароля не войти.
|
||||
|
||||
Оба окружения в одном K3s namespace. Один репозиторий, две ветки, два независимых пайплайна.
|
||||
|
||||
---
|
||||
|
||||
## Шаг 1: Создаём Hugo проект
|
||||
|
||||
```bash
|
||||
# Создаём новый Hugo сайт
|
||||
cd ~/projects
|
||||
hugo new site blog
|
||||
cd blog
|
||||
|
||||
# Инициализируем Git репозиторий
|
||||
git init
|
||||
git remote add origin https://git.example.com/user/blog.git
|
||||
|
||||
# Добавляем тему Blowfish как Git submodule
|
||||
git submodule add -b main https://github.com/nunocoracao/blowfish.git themes/blowfish
|
||||
|
||||
# Подтягиваем файлы submodule
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Удаляем дефолтный конфиг Hugo
|
||||
rm -f hugo.toml
|
||||
|
||||
# Создаём структуру для конфигов
|
||||
mkdir -p config/_default
|
||||
|
||||
# Копируем примеры конфигов из темы
|
||||
cp themes/blowfish/config/_default/*.toml config/_default/
|
||||
```
|
||||
|
||||
Структура после инициализации:
|
||||
|
||||
```
|
||||
blog/
|
||||
├── content/ ← статьи в Markdown
|
||||
├── static/ ← изображения, favicon
|
||||
├── themes/
|
||||
│ └── blowfish/ ← тема (Git submodule)
|
||||
└── config/
|
||||
└── _default/
|
||||
├── hugo.toml
|
||||
├── languages.ru.toml
|
||||
├── menus.ru.toml
|
||||
├── markup.toml
|
||||
└── params.toml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Шаг 2: Минимальная конфигурация
|
||||
|
||||
### hugo.toml
|
||||
|
||||
```toml
|
||||
baseURL = "https://blog.ru/"
|
||||
theme = "blowfish"
|
||||
defaultContentLanguage = "ru"
|
||||
```
|
||||
|
||||
### languages.ru.toml
|
||||
|
||||
```bash
|
||||
# Переименовываем файл языка для русского
|
||||
mv config/_default/languages.en.toml config/_default/languages.ru.toml
|
||||
```
|
||||
|
||||
```toml
|
||||
languageCode = "ru"
|
||||
languageName = "Русский"
|
||||
weight = 1
|
||||
title = "Мой Блог"
|
||||
|
||||
[params]
|
||||
displayName = "RU"
|
||||
isoCode = "ru"
|
||||
rtl = false
|
||||
dateFormat = "2 January 2006"
|
||||
|
||||
[params.author]
|
||||
name = "Ваше Имя"
|
||||
headline = "DevOps Engineer | Kubernetes | Homelab"
|
||||
```
|
||||
|
||||
### menus.ru.toml
|
||||
|
||||
```bash
|
||||
# Переименовываем файл меню
|
||||
mv config/_default/menus.en.toml config/_default/menus.ru.toml
|
||||
```
|
||||
|
||||
```toml
|
||||
[[main]]
|
||||
name = "Блог"
|
||||
pageRef = "posts"
|
||||
weight = 10
|
||||
|
||||
[[main]]
|
||||
name = "О сайте"
|
||||
pageRef = "about"
|
||||
weight = 20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Шаг 3: Первая статья
|
||||
|
||||
```bash
|
||||
# Создаём новую статью
|
||||
hugo new content posts/hello-world/index.md
|
||||
```
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: "Hello World"
|
||||
date: 2026-02-13
|
||||
draft: false
|
||||
description: "Первый пост на новом сайте"
|
||||
tags: ["test"]
|
||||
---
|
||||
|
||||
Это первый пост на blog.ru.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Шаг 4: Проверяем локально
|
||||
|
||||
```bash
|
||||
# Запускаем локальный сервер Hugo
|
||||
# -D: показывать черновики (draft: true)
|
||||
# --bind 0.0.0.0: доступен с любого IP в локальной сети
|
||||
hugo server -D --bind 0.0.0.0
|
||||
```
|
||||
|
||||
Открываем `http://192.168.11.10:1313/` (ваш IP) - сайт с Blowfish темой и первой статьёй.
|
||||
|
||||
Hugo автоматически пересобирает сайт при сохранении файлов - изменения видны сразу после обновления страницы в браузере.
|
||||
|
||||
---
|
||||
|
||||
## Шаг 5: Пушим в Gitea
|
||||
|
||||
```bash
|
||||
# Добавляем все файлы в Git
|
||||
git add .
|
||||
|
||||
# Создаём первый коммит
|
||||
git commit -m "Initial commit: Hugo + Blowfish v2.98.0"
|
||||
|
||||
# Переименовываем ветку в main (если по умолчанию master)
|
||||
git branch -M main
|
||||
|
||||
# Пушим в Gitea
|
||||
git push -u origin main
|
||||
|
||||
# Создаём ветку dev для development окружения
|
||||
git checkout -b dev
|
||||
git push -u origin dev
|
||||
|
||||
# Возвращаемся на main
|
||||
git checkout main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow: как я пишу статьи
|
||||
|
||||
**Пишу (ветка dev):**
|
||||
|
||||
```bash
|
||||
# Переходим в папку проекта
|
||||
cd ~/projects/blog
|
||||
|
||||
# Переключаемся на ветку dev
|
||||
git checkout dev
|
||||
|
||||
# Запускаем локальный предпросмотр
|
||||
hugo server -D --bind 0.0.0.0
|
||||
|
||||
# Создаём новую статью
|
||||
hugo new content posts/название-статьи/index.md
|
||||
|
||||
# Редактируем в любом редакторе, сохраняем, смотрим в браузере
|
||||
# Когда готово - коммитим
|
||||
git add .
|
||||
git commit -m "feat: новая статья про X"
|
||||
|
||||
# Пушим в dev ветку
|
||||
git push origin dev
|
||||
# → webhook срабатывает → автосборка → dev.blog.ru
|
||||
```
|
||||
|
||||
**Проверяю:**
|
||||
|
||||
Открываю `https://dev.blog.ru` (вводя логин/пароль Basic Auth) - вижу статью как её увидят читатели.
|
||||
|
||||
**Публикую:**
|
||||
|
||||
```bash
|
||||
# Переключаемся на main
|
||||
git checkout main
|
||||
|
||||
# Мержим изменения из dev
|
||||
git merge dev
|
||||
|
||||
# Пушим в production
|
||||
git push origin main
|
||||
# → webhook срабатывает → автосборка → blog.ru
|
||||
```
|
||||
|
||||
Золотое правило: **все изменения только через ветку `dev`**. В `main` - только через merge. Никогда не редактировать файлы находясь на `main`.
|
||||
|
||||
Почему это важно - расскажу отдельно, когда дойдём до того как я нарушил это правило и что из этого вышло.
|
||||
|
||||
---
|
||||
|
||||
## Что дальше
|
||||
|
||||
Локально всё работает. Но `hugo server` умрёт как только закрою терминал.
|
||||
|
||||
Нужно развернуть это в K3s: Hugo Builder который пересобирает сайт при каждом пуше, Nginx который раздаёт статику, SSL сертификаты, NFS хранилище. Об этом - в следующей части.
|
||||
|
||||
---
|
||||
|
||||
**Стек этой части:**
|
||||
- Hugo v0.155.3 extended
|
||||
- Blowfish v2.98.0
|
||||
- Gitea (внутренний)
|
||||
- Рабочая станция: Debian/Ubuntu
|
||||
Reference in New Issue
Block a user