Эта статья о том как эффективно, правильно и максимально удобно вести свой блог.
Я буду рассказывать о том как установить это все на ваш сервер и как сделать так чтобы изменив файл на локальном компьютере у вас все автоматически поменялось на вашем сайте. Как хостинг я буду использовать DigitalOcean. Если вы зарегистрируетесь по моей реферальной ссылке, то вы получите на счет $100, а я получу $25 - https://m.do.co/c/41bb5762da9a
Как раньше велись блоги
Я уже давно веду свой личный блог в интернете. Мой первый блог был на Wordpress, потом длительное время использовал Ghost. В 2020 году вести блог в какой-либо CMS не так эффективно, так как минусов значительно больше чем плюсов. Основной минус заключается в том, что контент не отделен от самой системы. Это ведет к большому количеству неудобств. Во-первых банально неудобно писать свои статьи. Писать сразу же в админке CMS довольно неудобно, специализированые нативные программы типа Ulysses, Scrivener, Typora во всех случаях выигрывают по удобству у админки CMS.
А если ты пишешь в каком-то своем редакторе, то тебе после этого нужно все переносить в админку CMS. И было бы не так плохо, если бы можно было бы просто скопировать и вставить. Но обычно, но всех этих CMS нужно отдельно загружать каждую картинку, морочиться с оформлением и форматированием. Это отнимает очень много времени.
А потом, если вы вдруг захотите поменять CMS, вам нужно будет сохранить все свои статьи. И тут вы столкнетесь с огромной потерей времени. Первый раз я переезжал с Wordpress на Ghost, тогда мне пришлось вручную сохранять все свои статьи и переносить их. После этого я переезжал уже с Ghost, и тогда я тоже вручную сохранял свои статьи, и поганый Ghost повставлял огромную кучу пробелов во все мои тексты.
Теперь, после всей этой боли я понимаю, что никогда не буду вести блог в какой-либо CMS.
Кроме CMS были и различные сервисы. Еще давно был популярен LiveJournal, но сейчас он полностью мертв. Потом был популярен Medium и какое-то время я писал статьи туда. Но прошло какое-то время и он превратился из бесплатного в условно бесплатный. То есть мне как автору не нужно платить за то, чтобы писать статьи, но вот пользователи, которые читают статьи на медиуме не могут читать много статей бесплатно. И мне как автору это не нравится. Это будто бы сильно сужает аудиторию, которая читает мои статьи.
Как ведутся блоги сейчас и что такое генератор статических сайтов
Наиболее правильный способ вести свой блог это использовать какой-либо генератор статических сайтов. Такой вариант лучше со всех сторон. Ваш блог будет сложнее взломать, так как уменьшается количество векторов атаки, ведь при таком варианте вы просто отдаете статичные файлы. Вам будет гораздо удобнее писать ваши статьи и управлять вашим контентом. Ваш сайт будет работать значительно быстрей, ведь тут нет динамически генерируемого контента и базы данных.
А самый большой плюс заключается в удобстве, в таком варианте вы сможете полностью написать свою статью в markdown формате в отдельной папке, добавить туда картинки простым перетягиванием, а потом просто закачав эту папку на сервер.
Кстати, генераторы статических сайтов используют не только для блогов. Я довольно давно писал о том, как я веду свою личную базу знаний. Там я использую Gitbook. По сути это точно такой же инструмент.
При использовании такого подхода вам не нужно больше заботиться о оформлении, вы думаете только над текстом и над структурой. Вам больше не нужно заходить в какие-то уродские админки и править что-то из них.
Сейчас постараюсь показать насколько удобно писать статью используя такой метод.
Как я пишу статьи
У меня есть папка, которая называется Drafts, она закреплена у меня в избранном в файндере. Когда у меня появляется идея написать о чем-то я создаю в ней новую папку с названием статьи.
Например, я хочу написать статью про QWERTY раскладку.
В своей папке с черновиками я создаю папку “qwerty”, и начинаю накидывать в нее любые материалы, которые нахожу: тексты, картинки и тд. Папка находится там пока я полностью не допишу статью.
Так же я сразу же создаю в этой папке файл “index.md”, в который начинаю сбрасывать какие-то мысли, заметки, ссылки и т.д.
Любые вставки картинок делаются протсо перетягиванием. После этого ничего делать не нужно. Не нужно менять путь, не нужно как-то форматировать текст или картинку. Нужно протсто ее перетащить.
После того как вы дописали вашу статью и она полностью готова, мы просто берем папку и переносим ее в другое место с нашим остальным готовым контентом. Дальше мы можем проверить на локалке, что все выглядит нормально.
Если с текстом все ок, то я просто нажимаю хоткей и все автоматически пушится в мой гит и публикуется на сервере.
Если вдруг кому-то интересно, я в самой конце подробно расскажу о том, как это настроить.
Что лучше? Hugo, Gatsby, Jekyll, Pelican?
Есть довольно много генераторов статических сайтов. Наиболее популярные из них - Hugo, Gatsby, Jekyll, Pelican.
Больше года я использовал Gatsby и он мне нравится, но сейчас использую Hugo уже около трех недель. Я полностью скопировал визуальный стиль из моей предыдушей темы, которую я использовал в Gatsby.
Для меня крайне важным параметром была простота работы с инструментом. Как минимум я хотел чтобы сам контент и картинки всегда были в одной папке. Некоторые инструменты не позволяют мне делать это.
Некоторые инструменты прямо говорят о том, что для них это не удобно.
Вот, например, один из авторов Pelican говорит о том, что держать контент и картинки в одном месте это бардак. Хотя я с ним не согласен. Поэтому Pelican явно не мой выбор, так как я не хочу сначала писать статью а потом еще и разбираться с тем, чтобы заморачиваться с тем чтобы правильно раскидывать картинки по разным директориям и париться с путями.
Выглядит Pelican после установки тоже довольно страшно. Я, конечно, понимаю, что любую систему можно заскинить, но уж лучше сразу дать выбрать тему, чем подсовывать насколько уродскую по-умолчанию.
Одно из самых шикарных решений в Pelican - писать светлым текстом на светлом фоне.
Jekyll мне тоже не подошел. Выглядит с дефолтной темой он значительно лучше, чем Pelican, но нормальных готовых тем все равно значительно меньше, чем для Hugo или Gatsby.
Но все-таки этот вариант мне тоже не понравился. Опять же, главный критерий для меня это уметь работать когда контент и картинки находятся в одной папке. Jekyll по-умолчанию этого не умеет.
Так же, я прочитал о том, что если использовать изображения в статьях, то нужно делать по две копии каждой картинки, одну для превью, а вторую для самого изображения. Тут я понял, что этот вариант мне совмем не подходит.
Кроме того, Jekyll написан на Ruby. Многие считают его красивым и мощным языком, но мне он не по душе. Его довольно сложно читать, такие языки называют “write-only”, писать на таких языках проще чем читать его код. Довольно много магии, нет статической типизации и жрет память как сумасшедший. Учить его тоже желания не возникает, так как он крайне редко используется в больших проектах, если даже проект и писался на нем, то с развитием он все равно переписывается на что-то вроде java.
Так же, я столкнулся с довольно непонятной ошибкой, когда загрузил свой контент в Jekyll. Он ругался на то, что мои изображения…..ммм…… не могут быть прочитаны из-за какой-то недопустимой последовательности байтов в UTF-8. Честно говоря, до сих пор не могу понять что это значит, но в любом случае других картинок у меня нет.
Gatsby, как я уже говорил раньше мне нравится. В Gatsby это компилятор на React. А React я сильно люблю, поэтому и Gatsby мне тоже сразу же понравился. Он очень гибкий, на нем за очень небольшое количество времени можно сделать все, что угодно. Тут сразу же есть поддержка SCSS, Typography.js да и вообще есть огромная поддержка плагинов.
Но в любом случае, это вам не руби, знания реакта и GraphQL вам точно пригодятся в будущем.
Самым большим недостатком Gatsby является то, что там нет лайв релоада. Представьте, у вас работает сайт и вы захотели добавить новый пост. По сути вам нужно закачать этот пост на сервер, потом выключить сервер, сгенерировать статические файлы пока сервер лежит, и потом опять включить сервер. Звучит странно.
Еще не нравится, что Gatsby это какая-то безумно долгая генерация статического контента из ваших маркдаун исходников.
Например, все мои исходники у меня на ловальной машине генерируется целых 140 секунд. Это чудовищно долго.
И даже если Gatsby сделает кэш и вы запустите билд опять, то Gatsby все равно потратит на это целых 14 секунд. На сервере, который не такой мощный как моя локальная машину это занимает около минуты.
Для примера, генерация всего на Hugo занимает меньше секунды. Pelican и Jekyll тоже генерируют все очень быстро.
![CleanShot 2020-10-23 at 18.23.11@2x](../../../Library/Application Support/CleanShot/media/media_8MVsxJVdGY/CleanShot 2020-10-23 at 18.23.11@2x.png)
Собственно из-за этого я перешел на Hugo.
Почему я выбрал Hugo?
Сейчас как по мне, это наиболее удобный инструмент для моих задач. Он работает на Go, генерирует все с безумной скоростью. У Hugo очень большая и качественно написанная документация. На нем можно сделать практически все, что угодно.
Он удовлетворяет всем моим потребностям, он сразу же умеет работать когда контент и картинки находятся в одной папке. Он очень быстрый и довольно легко настраивается.
Я буквально за час смог подностью скопировать всю свою тему из Gatsby - как стили так и саму логику поведения.
Слева Gatsby, справа Hugo.
Недостатки Hugo
Есть и недостатки. Больше всего мне не понравилось то, что нельзя одновременно использовать две темы на разные разделы сайта. Нельзя так же создавать кастомный дизайн и кастомный layout для каких-то страниц.
Вы можете использовать только layout для single страниц (по факту это страница с самой статьей) и layout для list (это страница для списком страниц)
Например, я для себя хотел еще сделать страницу со своим резюме. Для этого в Hugo есть большое количество довольно интересно выглядящих тем.
Сделать все как я хотел я не смог, но я выкрутился добавив обычную статичную страницу в папку static
И сейчас по ссылке https://devpew.com/cv Hugo нормально отображает мое резюме.
Работает этот вариант отлично, но я думаю, что вам следует знать о таких вот ограничениях. К примеру Gatsby в этом плане значительно гибче. Там можно сделать любую структуру.
Как это работает технически
В начале статьи я показал как я веду блог. Я говорил о том, что я могу просто исправить опечатку в локальном файле, нажать хоткей и у меня все автоматически обновится на сервере. Сейчас расскажу про это подробнее.
По факту когда я нажимаю горячую клавишу у меня выполняется скрипт, который пушит мои изменения на мой сервер с GitLab
cd /Users/dm/projects/hugo/content && git add . && git commit -m 'just fix' && git push origin master
После того как пуш приходит на мой GitLab сервер там срабатывает CI/CD джоба. После этого эту джобу выполняет Gitlab runner. Если вы установили GitLab, то по-умолчанию там не установлен и не настроен gitlab-runner. Так что установим и настроем его.
Установка gitlab-runner
Установка gitlab-runner:
export GITLAB_RUNNER_DISABLE_SKEL=true; sudo -E apt-get install gitlab-runner
В мануале написано, что нужно сделать нового пользователя. Это делается командой:
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
После этого нам нужно создать папку в которой будет наш скрипт и убедиться, что там все ок с правами.
cd /home/gitlab-runner/
mkdir q
chmod gitlab-runner:gitlab-runner /home/gitlab/q
Создаем в этой папке скприпт, который будет запускаться:
/home/gitlab/q
touch deploy.sh
chmod +x deploy.sh
chmod gitlab-runner:gitlab-runner deploy.sh
И добавляем в него:
#!/bin/sh
ssh -A root@<YOURIP> "cd /root/hugo_blog/content && git pull origin master"
Существует довольно много способов обновлять контент. В интернете я видел способ при котором удаляют папку public, заново генерируют статичный контент и после этого синхронизируют все через rsync. Мне такой способ кажется излишним, так как Hugo и без этого способен на лету подхватить изменения и на лету, довольно быстро сгенерить статичные файлы.
Важно так же убедиться, что на сервере, на котором развернут Hugo, в файле ~/.ssh/authorized_keys
есть ключ от сервера Gitlab.
После установки gitlab-runner нам надо будет добавить новый раннер:
gitlab-runner register
Когда запустите команду у вас спросят название раннера, теги и token. Token нужно взять на странице настроек.
После того как вы зарегистрировали новый раннер вы можете посмотреть список раннеров командой:
gitlab-runner list
В первый раз можете запусить раннер командой:
gitlab-runner --debug run
Вы сможете видеть детали джобы.
Если все ок, то вы сможете запустить раннер.
gitlab-runner start
После этого, если ошибок нет, то можем выполнить команду и посмотреть статус:
root@gitlab:~# gitlab-runner status
Runtime platform arch=amd64 os=linux pid=2360 revision=ece86343 version=13.5.0
gitlab-runner: Service is running!
Настройка хука
Теперь нам нужно настроить сам хук. Нужно просто добавить в репу файл с названием .gitlab-ci.yml
В котором будет ссылка на bash (или другой) скрипт, который вы будете запускать. У меня этот файл выглядит вот так:
stages:
- deploy
deploy:
stage: deploy
script:
- echo "SCRIPT RUN!!!"
- cd /home/gitlab-runner/q
- /bin/bash deploy.sh
Проверка работы хука
Теперь просто выполним пулл в нашу настроенную репу
Если все ок, то вы увидим зеленый значок. В этом случае gitlab-runner должен выполнить наш скрипт, который пойдет на сервер Hugo и сделает там pull. После этого контент нашего блога поменяется.
Если нет Gitlab
Если у вас не установлен gitlab, а есть только сервер с Hugo, вы можете прям на нем установить гит и настроить в неи post-receive hook. Это делается значительно проще, чем в варианте с гитлабом, но мне не нравится этот вариант тем, что в этом варианте контента нет в моей основной репе.
Дополнение
После того как я установил Hugo на свой сервер на Ubuntu он заводился, но не работал. Я потратил довольно много времени, чтобы разобраться почему. Оказалось, что в Ubuntu в репе какая-то дико старая версия
Hugo Static Site Generator v0.40.1 linux/amd64 BuildDate: 2018-04-25T17:16:11Z
Например, в brew сейчас находится версия:
Hugo Static Site Generator v0.76.5/extended darwin/amd64 BuildDate: unknown
Разница между этими версиями 1 год и 6 месяцев
Поэтому я просто скачал deb пакет
wget https://github.com/spf13/hugo/releases/download/
И установил его
sudo dpkg -i hugo*.deb