Как написать systemd unit-файл для автозагрузки своего сервиса

Здесь покажу как писать инитники для автозапуска какого-либо демона в системе с systemd.

Systemd оперирует unit-файлами в качестве конфигурационных файлов. Это как .conf-файл для upstart или init-скрипты для initd. Unit-файлы также могут описывать и другие системные сущности, но в данном случае они нас интересуют как конфиг для автостарта сервиса. В Ubuntu 16.04 они лежат в /etc/systemd/. Напишем свой unit-файл.

Допустим у нас есть программа, которую мы хотим запускать как демон. Вот здесь я писал как создать telegram-бота. У меня получился исполняемый файл, который запускается и висит ждет сообщений. Теперь хочу чтобы он как демон стартовал при загрузке системы.

Создаем такой файл:

[Unit]
Description=TelegramBotMonitoring
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/telegram-site-monitoring -telegrambottoken 397______:___________WRDsIU -chatid -14____640
Restart=always

[Install]
WantedBy=multi-user.target

и кладем его в /etc/systemd/system/telegram-bot.service

Конфиг похож на обычный ini-файл:

  • After — запускать этот юнит после определенных демонов или целей (цель — это набор юнитов). Здесь указан network.target, это значит, что демон запустится после того как поднимутся сетевые интерфейсы.
  • Type — тип того, как запускается демон. Чаще всего используется simple, forking или one-shot. simple — демон запускается и начинает ожидать на консоле и не отфоркивается. forking — демон запускается, потом форкается и завершает родительский процесс. Многие программы именно так и запускаются, чтобы перейти в background режим. Например, nginx запускается по такой схеме. one-shot — используется для запуска скриптов которые запускаются, отрабатывают и завершаются. В моем случае это не скрипт и программа не форкается , поэтому тип — simple
  • ExecStart — команда для запуска демона.
  • Restart — рестартовать демон, если он завершится/упадет. При always systemd будет перезапускать демон независимо от того почему он завершился. Можно указать on-failure, тогда будет перезапускаться если демон вышел с ненулевым кодом возврата или был завершен по сигналу (kill DAEMONPID)
  • WantedBy — говорим, что запускать этот демон когда система грузится в multi-user режиме

Далее делаем релоад systemd:

# systemctl daemon-reload

И добавляем созданный юнит в автозагрузку:

# systemctl enable telegram-bot.service
Created symlink from /etc/systemd/system/multi-user.target.wants/telegram-bot.service to /etc/systemd/system/telegram-bot.service.```

Все. Сервис добавлен в автозагрузку, но еще не запущен. Запустим:

# systemctl start telegram-bot

Запустился:

# systemctl status telegram-bot
● telegram.service - TelegramBotMonitoring
   Loaded: loaded (/etc/systemd/system/telegram-bot.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2017-07-13 17:10:19 MSK; 5s ago
 Main PID: 1825 (telegram-site-m)
    Tasks: 4
   Memory: 4.4M
      CPU: 39ms
   CGroup: /system.slice/telegram-bot.service
           └─1825 /usr/local/bin/telegram-site-monitoring -telegrambottoken 3972____:__________Gi03WRDsIU -chatid -14____40

Jul 13 17:10:19 ubuntu systemd[1]: Started TelegramBotMonitoring.
Jul 13 17:10:19 ubuntu telegram-site-monitoring[1825]: 2017/07/13 17:10:19 {}
Jul 13 17:10:19 ubuntu telegram-site-monitoring[1825]: 2017/07/13 17:10:19 Authorized on account
Jul 13 17:10:19 ubuntu telegram-site-monitoring[1825]: 2017/07/13 17:10:19 Config file: config.json
Jul 13 17:10:19 ubuntu telegram-site-monitoring[1825]: 2017/07/13 17:10:19 ChatID: 
Jul 13 17:10:19 ubuntu telegram-site-monitoring[1825]: 2017/07/13 17:10:19 Starting monitoring thread

Запуск bash скрипта в фоновом режиме через Systemd

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

Для реализации работы в фоне сначала написал Linux — демон на C, но потом решил что для моей задачи это слишком, и реализовал это при помощи Systemd.

Для начала нужно убедиться, что ваш дистрибутив работает с Systemd, командой:

readlink /proc/1/exe
если вывод будет /sbin/init — то у вас используется SysV, и вам нужно либо обновить дистрибутив, как в моем случае, я обновил Debian 7 Wheezy до Debian 8 Jessie, либо реализовать работу в фоновом режиме другим способом.

Если вывод такой:
/lib/systemd/systemd — то все в порядке, у вас Systemd.

Systemd осуществляет свою работу с помощью так называемых юнитов systemd.
Юнит (Unit) — это конфигурационный файл, расположенный в одной из директорий:

/run/systemd/system/ — юниты, созданные в рантайме. Этот каталог приоритетнее каталога с установленными юнитами из пакетов.
/etc/systemd/system/ — юниты, созданные и управляемые системным администратором. Этот каталог приоритетнее каталога юнитов, созданных в рантайме. В этом каталоге мы и будем создавать свой юнит.

Переходим в каталог /etc/systemd/system/ и создаем в нем, либо копируем какой-либо существующий файл, к примеру sshd.service, и в нем пишем:

[Unit]
Description=MyBashScript
After=syslog.target
 
[Service]
 
ExecStart=/bin/bash '/home/user/scripts/script.sh'
Type=forking
 
[Install]
WantedBy=multi-user.target
Alias=bash.service

Подробнее о каждой секции:
Секция [Unit]:
Содержит общую информацию о сервисе, его описание, и то, что он должен стартовать после запущенного демона Syslog.

Секция [Service]
Непосредственная информация о нашем сервисе.
Параметр ExecStart указывает на исполняемый файл нашего сервиса. Нужно указывать абсолютные пути, в случае с bash-скриптом путь до скрипта берем в одинарные кавычки.
Type=forking означает, что запускаемый скрипт будет работать в режиме демона. Если мы хотим, чтобы скрипт выполнился один раз, то указываем Type=simple.

Секция [Install]
Последняя секция [Install] содержит информацию о цели, в которой сервис должен стартовать. В данном случае мы хотим, что сервис должен быть запущен, когда будет активирована цель multi–user.target (это аналог init 3 в SysV).
Alias=bash.service — для удобства создадим алиас, чтобы проще управлять нашим сервисом через systemctl.

Это работающий файл сервиcа Systemd, с небольшим функционалом. Сохраняем файл, и выполняем команду systemctl daemon-reload, чтобы Systemd узнал о нашем сервисе, и вы могли его запустить командой systemctl start bash.service.
У меня запустить получилось не с первого раза, так как сначала я указал не абсолютный путь в параметре ExecStart секции [Service]. После исправления Systemd все равно ругался на ту же ошибку, помогла перезагрузка.

Для просмотра состояния, старта, остановки, перезагрузки, включения или выключения системных сервисов используется команда systemctl. В более ранних версиях Systemd использовались команды service и chkconfig, они по прежнему включены в систему, в основном для обратной совместимости.

Ниже представлены основные команды systemctl:

systemctl start name.service – запуск сервиса.
systemctl stop name.service — остановка сервиса
systemctl restart name.service — перезапуск сервиса
systemctl try-restart name.service — перезапуск сервиса только, если он запущен
systemctl reload name.service — перезагрузка конфигурации сервиса
systemctl status name.service — проверка, запущен ли сервис с детальным выводом состояния сервиса
systemctl is-active name.service — проверка, запущен ли сервис с простым ответом: active или inactive
systemctl list-units —type service —all – отображение статуса всех сервисов
systemctl enable name.service – активирует сервис (позволяет стартовать во время запуска системы)
systemctl disable name.service – деактивирует сервис
systemctl reenable name.service – деактивирует сервис и сразу активирует его
systemctl is–enabled name.service – проверяет, активирован ли сервис
systemctl list-unit-files —type service – отображает все сервисы и проверяет, какие из них активированы
systemctl mask name.service – заменяет файл сервиса симлинком на /dev/null, делая юнит недоступным для systemd
systemctl unmask name.service – возвращает файл сервиса, делая юнит доступным для systemd

Для более подробного знакомства с Systemd рекомендую почитать:

Настраиваем удобный npm проект для себя и команды или немного о современных фронтенд инструментах

Всем привет. Недавно мне попалась задача настроить оборот приватных npm пакетов. Все звучало очень интересно и многообещающе пока не оказалось, что делать там совсем не много. Тут бы все и закончилось, но возникла вторая задача — написать демо репозиторий для npm пакета, который можно было бы взять, клонировать и на его базе быстро создать что-то полезное и в едином стиле.

 

В результате получился проект с настроенным форматированием, кодстайлом, тестами на каждый пулл, лимитами на покрытие кода, отчетом о покрытии кода и автоматической документацией. Плюс удобная публикация в npm. Подробности о настройке — под катом.

Требования

 

Cначала я прикинул что у нас уже есть:

 

  • Новые проекты пишутся на TypeScript
  • Кроме новых проектов, есть еще куча проектов на чистом JavaScript
  • Есть требования писать тесты и результаты нужно отправлять на анализ

 

Потом прикинул свои хотелки — раз уж есть время и желание, почему бы не разгуляться. Что я хочу еще:

 

  • Хочу единый стиль форматирования
  • Хочу единый стиль TypeScript
  • Хочу документацию, но не хочу ее писать
  • Вообще хочу все автоматизировать по максимуму. Что бы фыр-фыр-фыр и в продакшн

 

В итоге требования оформились в следующее:

 

  • Модуль должен быть на TypeScript и проверен с помощью TsLint
  • Модуль должен быть используемым из-под TypeScript и из-под JavaScript
  • Тесты должны быть настроены на git hook, минимальное покрытие кода должно быть тоже настроено, статистика должна быть
  • Форматирование должно быть настроено
  • Документация должна создаваться из кода
  • Публикация должна быть удобной и единообразной
  • Все что можно должно быть автоматизировано

 

Вроде бы неплохо, нужно пробовать.

 

Предварительные телодвижения

 

Создаем (клонируем) репозиторий, инициализируем package.json, ставим локально TypeScript. Вообще все зависимости ставим локально, т.к. все будет уходить на сервер. Не забываем фиксировать зависимости версий.

 

git init
npm init
npm i -D typescript
./node_modules/.bin/tsc --init

 

Тут же на месте нужно подправить tsconfig.json под себя — выставить target, libs, include/exclude, outDir и остальные опции.

 

Стиль форматирования

 

Для сохранения единообразия форматирования я взял два инструмента. Первый это файл .editorconfig. Он понимается всеми основными IDE (WebStorm, VSCode, Visual Studio и т.д.), не требует установки ничего лишнего и работает с большим количеством типов файлов — js, ts, md, и так далее.

 

#root = true

[*]
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100
indent_size = 4

[*.md]
trim_trailing_whitespace = false

 

Теперь автоформатирование будет вести себя более-менее одинаково у меня и у коллег.

 

Второй инструмент — prettier. Это npm пакет, который проверяет, и по возможности, автоматически корректирует ваше форматирование текста. Установите его локально и добавьте первую команду в package.json

 

npm i -D prettier

 

package.json

 

"prettier": "prettier --config .prettierrc.json --write src/**/*.ts"

 

У prettier нет команды init, так что конфигурировать его нужно вручную. Создайте .prettierrc.json в корне проекта вот примерно с таким спорным содрежанием (если что — пост совсем не о том, какие кавычки лучше, но вы можете попробовать)

 

.prettierrc.json

 

{
    "tabWidth": 4,
    "useTabs": false,
    "semi": true,
    "singleQuote": true,
    "trailingComma": "es5",
    "arrowParens": "always"
}

 

Теперь создайте папку src, в ней создайте index.ts с каким-то условным содержанием и попробуйте запустить prettier. Если ему не понравится ваше форматирование — он его исправит автоматически. Очень удобно. Если вы не хотите вспоминать об этом только во время коммита/пуша можно настроить его на автозапуск или поставить расширение для студии.

 

Стиль кода

 

Со стилем кода все тоже не сложно. Для JavaScript есть eslint, для TypeScript есть tslint. Ставим tslint и создаем tsconfig.js для хранения настроек

 

npm i -D tslint
./node_modules/.bin/tslint --init

 

package.json

 

"lint": "tslint -c tslint.json 'src/**/*.ts' 'tests/**/*.spec.ts'"

 

Вы можете написать собственные правила, а можете использовать уже существующие правила с помощью параметра extend. Вот, например, конфиг от airbnb.

 

Разработчики tslint шутят

 

Есть важный момент — tslint и prettier пересекаются по функционалу (например в длинне строки или «висящих» запятых). Так что, если вы будете использовать оба — нужно будет следить за соответствием или отказаться от чего-то.

 

И еще, для тех кто хочет проверять не все файлы, а только staged — есть пакет lint-staged

 

Тесты

 

Что нам нужно от тестов прежде всего? Во-первых, чтобы они запускались автоматически, во-вторых контроль покрытия, в-третьих какой-то отчет, желательно в lcov формате (если что — lcov отлично понимается разными анализаторам — от SonarQube до CodeCov). Автоматизацией мы займемся чуток позже, пока настроим сами тесты.

 

Ставим karma, jasmine и весь соответствующий ей обвес

 

npm i -D karma karma-jasmine jasmine karma-typescript karma-chrome-launcher @types/jasmine
./node_modules/.bin/karma init

 

Немного модифицируем karma.conf.js и сразу настроим работу с покрытием

 

karma.conf.js

 

И, конечно, не забываем дописать новую команду в package.json

 

package.json

 

"test": "karma start"

 

Если вы используете или планируете использовать CI то лучше поставить HeadlessChrome:

 

npm i -D puppeteer

 

И доконфигурировать Karma (Chrome исправить на ChromeHeadless) плюс еще кое-что. Правки можно посмотреть в демо репозитории.

 

Запустите тесты, проверьте что все работает. Заодно проверьте отчет о покрытии (он находится в папке coverage) и уберите его из-под контроля версий, в репозитории он не нужен.

 

Отчет:

 

 

Стиль коммитов

 

Коммиты тоже можно унифицировать (и заодно довести кого-то до белого каления, если переборщить, так что лучше без фанатизма). Для этого я взял commitizen. Он работает в форме диалога, поддерживает conventional-changelog формат (из его коммитов можно создавать changelog) и для него есть VsCode плагин

 

npm i -D commitizen
npm i -D cz-conventional-changelog

 

cz-conventional-changelog это адаптер, который отвечает за вопросы, и как следствие, за формат ваших коммитов

 

Добавьте новую команду в scripts секцию

 

"commit":"git-cz"

 

И новую секцию package.json — config для commitizen

 

"config": {
        "commitizen": {
            "path": "./node_modules/cz-conventional-changelog"
        }
    }

 

Диалог с commitizen выглядит так:

 

 

Документация

 

Теперь к документации. Документация у нас будет двух видов — из кода и из коммитов. Для документации из кода я взял typedoc (аналог esdoc но для TypeScript). Он очень просто ставится и работает. Главное не забудьте убрать результаты его трудов из-под контроля версий.

 

npm i typedoc -D

 

и обновляем package.json

 

package.json

 

"doc": "typedoc --out docs/src/ --readme ./README.md"

 

Флаг —readme заставит включить readme в главную страницу документации что удобно.

 

Второй тип документации это changelog, и с ним нам поможет conventional-changelog-cli пакет.

 

npm i -D conventional-changelog-cli

 

package.json

 

"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"

 

От angular здесь только форматирования и ничего больше. Теперь для того что бы обновить changelog достаточно запусть npm run changelog. Главное внимательно писать коммиты. Ну мы же всегда пишем идеальные коммиты, так что это проблемой быть не должно.

 

Билд

 

Поскольку наш пакет должен работать и для JavaScript, нам нужно превратить TypeScript в JavaScript. Кроме того, неплохо было бы сделать еще и минифицированный бандл, просто на всякий случай. Для этого нам понадобится uglifyjs и немного подправить package.json

 

npm i -D uglifyjs

 

package.json

 

"clean":"rmdir dist /S /Q",
"build": "tsc --p ./ --sourceMap false",
"bundle": "uglifyjs ./dist/*.js --compress --mangle --output ./dist/index.min.js"

 

Кстати, если вы хотите контролировать размер вашего проекта, есть еще два интересных пакета

 

 

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

 

Автоматизация

 

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

 

Для этого нам понадобится еще один пакет — husky. Он переписывает git hooks и вызывает сопоставленные команды из package.json. Например, когда вы делаете коммит, сработает precommit, push — prepush и так далее. Если скрипт вернет ошибку, коммит упадет.

 

npm i -D husky

 

package.json

 

"precommit":"npm run prettier",
"prepush": "call npm run lint && call npm run test"

 

Тут есть важный нюанс, использование call синтаксиса не кроссплатформенно и на unix системах не взлетит. Так что если хотите все сделать по-честному придется поставить еще и npm-run-all пакет, он делает все тоже самое но кросплатформенно.

 

Публикация

 

Ну вот мы и дошли до публикации нашего (пусть и пустого) пакета. Давайте подумаем, что мы хотим от публикации?

 

  • Еще раз все протестировать
  • Собрать билд артефакты
  • Собрать документацию
  • Поднять версию
  • Запушить теги
  • Отправить в npm

 

Руками это все делать — грустно. Или забудешь что-то, или чеклист писать нужно. Нужно тоже автоматизировать. Можно поставить еще один пакет — unleash. А можно воспользоваться нативными хуками самого npm — preversion, version, postversion, например вот так:

 

"preversion": "npm run test",
"version": "call npm run clean && call npm run build && npm run bundle && call npm run doc && call npm run changelog && git add . && git commit -m 'changelogupdate' --no-verify",
"postversion": "git add . && git push && git push --tags",

 

Осталось указать для package.json что включать в пакет, точку входа и путь к нашим типам (не забудьте указать —declaration флаг в tsconfig.json что бы получить d.ts файлы)

 

package.json

 

"main": "./dist/index.min.js",
"types": "./dist/index.d.ts",
"files": [
        "dist/",
        "src/",
        "tests/"
    ]

 

Ну вот вроде бы и все. Теперь достаточно выполнить

 

npm version ...
npm publish

 

И все остальное будет сделано в автоматическом режиме.

61 способ улучшить SEO вашего сайта

Недавно мы закончили курс по SEO в Нетологии и составили для себя чек-лист того, что обязательно нужно сделать на сайте «Я люблю ИП» для поисковой оптимизации. Но эти советы универсальны для любого проекта. В статье вы найдёте список практических рекомендаций со всего курса из 13 лекций от 8 разных специалистов, а также полезные ссылки и сервисы, которые помогут вам улучшить SEO вашего сайта.

 

Для кого эта статья:

 

  • для веб-дизайнеров и разработчиков, которые хотят создавать сайты, изначально оптимизированные под SEO,
  • для владельцев интернет-ресурсов, которые хотят самостоятельно разобраться в SEO, чтобы увеличить поисковый траффик.

 

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

Работы по SEO в основном состоят из 5 этапов:

 

  1. Технический аудит сайта.
  2. Аудит коммерческих факторов.
  3. Подбор семантического ядра.
  4. Внутренняя и внешняя оптимизация сайта.
  5. Наращивание ссылочной массы.

 

Технический аудит сайта

 

1) Проверьте, все ли страницы сайта находятся в поиске:

 

  • по количеству результатов в поиске (в Google — при помощи site:site.ru, в Яндексе — при помощи host:site.ru),
  • в Яндекс.Вебмастер (Индексирование → Страницы в поиске) или в Google Search Console (Индекс Google → Статус индексирования).

 

2) Проверьте наличие дублей на сайте. Дубли — это страницы с одинаковым содержанием, но с разными URL. Дубли могут быть полные (если контент совпадает на 100 %) или частичные (с высоким % совпадения). Дубли страниц необходимо удалять.

 

3) Проверьте наличие пустых страниц (которые не содержат контента). Пустые страницы можно:

 

  • удалить,
  • закрыть от индексации (в файле robots.txt, см. ниже),
  • наполнить контентом.

 

4) Проверьте наличие мусорных страниц (которые не содержат полезного контента). Мусорные страницы можно:

 

  • закрыть от индексации,
  • сделать полезными.

 

5) Проверьте наличие файла robots.txt. Это текстовый файл в корневой директории сайта, который содержит специальные инструкции для поисковых роботов. Подробнее см. справку Яндекса и Google. Размер файла не должен превышать 32 КБ.

 

6) В файле robots.txt можно указать общие правила для всех поисковых систем и отдельно для Яндекса. В правилах для Яндекса должна быть дополнительно указана директива Host (главное зеркало вашего сайта с www или без) и директива Sitemap с ссылкой на карту вашего сайта. Проверить файл robots.txt можно в Яндекс.Вебмастере.

User-agent: *
Disallow: /contacts/
Sitemap: http://www.iloveip.ru/sitemap.xml

User-agent: Yandex
Disallow: /contacts/
Host: www.iloveip.ru
Sitemap: http://www.iloveip.ru/sitemap.xml

Пример файла robots.txt с нашего сайта

 

7) Проверьте наличие файла sitemap.xml. Это аналог карты сайта, предназначенный специально для поисковых роботов. Подробнее см. справку Яндекса и Google. Создать карту сайта можно по ссылке. Проверить файл sitemap.xml можно в Яндекс.Вебмастере.

 

8) Проверьте наличие «битых» ссылок (ссылок на несуществующие или недоступные страницы). Необходимо удалять все битые ссылки, как внешние, так и внутренние. Проверить битые ссылки можно в программе Screaming Frog SEO Spider Tool (загружается на компьютер, есть бесплатная версия) или онлайн с помощью инструмента Технический анализ от SeoWizard (сервис платный). Также битые ссылки можно проверить в Яндекс.Вебмастере: Индексирование → Статистика обхода (см. HTTP код 404).

 

9) Проверьте наличие редиректов на сайте. Виды редиректов:

 

  • 301 — запрошенный документ окончательно перенесен на новый URL,
  • 302 — запрошенный документы временно доступен по другому URL.

 

Редиректами лучше не злоупотреблять, так как наличие на страницах сайта ссылок, ведущих на страницы с редиректом, способствует «утере» ссылочного веса.

 

Проверить можно в Яндекс.Вебмастере: Индексирование → Статистика обхода (см. HTTP код страницы).

 

10) Проверьте скорость загрузки сайта (должна быть менее 3 сек). Это один из важных факторов, который влияет на ранжирование сайта поисковыми системами. Проверить можно с помощью Google PageSpeed или в Google Search Console (Сканирование → Статистика сканирования → Время, затраченное на загрузку страницы).

 

11) Настройте ошибку 404 для удалённых или несуществующих страниц. Это можно сделать в файле .htaccess. Подробнее см. справку Яндекса.

 

12) Проверьте ответы сервера и файл .htaccess. Наиболее частые ошибки, которые встречаются:

 

  • Доступны обе версии сайта с www и без (например, site.ru и www.site.ru). Это плохо влияет на индексацию, так как поисковик старается исключать дубли и может выбрать в качестве оригинала совсем не ту страницу, которую вы продвигаете.
  • Отсутствуют редиректы для страниц со « /» на конце и без него. Если страницы сайта без слэша на конце и со слэшем отдают ответ сервера 200 (страница доступна), то попадая в индекс поисковых систем они представляют собой полные дубли.

 

13) Проверьте правильность URL. Неконечные страницы (разделы, подразделы) должны содержать «/» на конце URL, а конечные страницы (страницы товаров, статей) не должны содержать «/». Но применять этот формат рекомендуется только к новым страницам, так как для старых это приведёт к потере возраста документа.

 

14) Старайтесь использовать «ЧеловекоПонятныеУРЛы» (сокращенно «ЧПУ») или красивые и дружественные адреса URL. Пример отсутствия ЧПУ: yoursite.net/viewpage.php?page_id=23. Основные рекомендации:

 

  • можно использовать иностранные слова (/contacts/) или транслит (/kontakty/),
  • в качестве разделителя между словами используйте дефис «-»,
  • между разделителями «/» в адресе URL должно быть не более 2–3 слов,
  • длина URL не должна превышать среднее значение по конкурентам.

 

15) Соблюдайте иерархию папок в URL. Например:

 

site.ru/название-раздела/назавание-подраздела/конечная-страница

 

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

 

16) Проверьте отображение сайта на мобильных устройствах. Это можно сделать в Яндекс.Вебмастере (Инструменты → Проверка мобильных страниц) или в Google Search Console.

 

17) Укажите в head кодировку страниц meta charset=«utf-8».

 

18) Проверьте наличие и уникальность тегов title, description и h1 на каждой странице.

 

19) Тег title должен быть максимально близко к началу head.

 

20) Старайтесь добавить в тег title все ключевые слова, при этом самое популярное ключевое слово должно быть ближе к началу тега.

 

21) Максимальная длина тега title — 150 символов, оптимально — 60 символов.

 

22) В теге title не должны повторяться одинаковые слова (максимум не более 2 раз), можно использовать синонимы, близкие слова или другие слова из запросов. Например: Займ в банке под залог комнаты. Получить кредит под залог комнаты в Москве.

 

23) Для разделения разных фраз в теге title (например, названия страницы и сайта) используйте символ «|».

 

24) Тег description не влияет на ранжирование сайта прямо, но поисковые системы могут использоваться его содержимое для сниппета сайта при выдаче.

 

25) Длина description может быть от 100 до 250 символов, оптимально — 155 символов. Обычно это одно-два осмысленных предложения для описания страницы, включая поисковые запросы.

 

26) Укажите в head метаданные по Open Graph Protocol для правильного представления сайта в социальных сетях.

 

27) Добавьте в корневую директорию фавикон сайта.

 

28) Стили и скрипты должны загружаться в head отдельными файлами.

 

29) На странице может быть только один заголовок h1.

 

30) Заголовок h1 не должен копировать title.

 

31) Заголовок h1 может содержать от 1 до 7 слов и должен включать точное вхождение главного поискового запроса. Например: Займ под залог комнаты.

 

32) Старайтесь не использовать вложенные теги в теге h1 (например, span, em, a href и т. д.).

 

33) Соблюдайте последовательность заголовков h2-h6 и включайте в них остальные ключевые слова. Теги h2-h6 должны использоваться только для разметки SEO-текстов.

 

34) Используйте семантическую вёрстку (для параграфов — p, а не div), старайтесь включать ключевые слова в списки, таблицы, картинки (теги alt, title), выделения (em, strong).

 

35) Атрибуты alt и title для картинок должны отличаться. Alt — это альтернативный текст для картинки, если она не загрузилась. Title — это заголовок картинки, который всплывает при наведении на картинку, а также выходит в поиске.

 

36) Добавьте на сайт микроразметку Shema.org. Валидатор микроразметки в Яндекс.Вебмастере.

 

37) Если вы планируете переезд сайта на https, почитайте эту статью.

 

Аудит коммерческих факторов

 

38) Коммерческие факторы важны для коммерческих сайтов.

 

39) На сайте должны присутствовать контакты:

 

  • телефоны,
  • онлайн-консультант,
  • обратный звонок,
  • адрес, схема проезда,
  • график работы.

 

40) Разместите на сайте юридическую информацию:

 

  • договор-оферту, условия оказания услуг,
  • реквизиты компании,
  • условия обмена/ возврата,
  • условия доставки.

 

41) Разместите на сайте ассортимент:

 

  • прайс-лист,
  • количество товаров в наличии,
  • скидки, акции.

 

42) Добавьте информацию, которая вызывает доверие:

 

  • отзывы,
  • портфолио (примеры работ),
  • видео,
  • вакансии.

 

43) Разместите электронную почту на своём домене (например, info@site.ru).

 

44) Если на сайте публикуются новости, следите за их обновлением.

 

45) В копирайте (с) укажите текущий год.

 

46) Стремитесь, чтобы дизайн сайта был современным и адаптированным для мобильных устройств.

 

Подбор семантического ядра

 

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

 

47) Прежде, чем перейти к подбору семантического ядра, необходимо понять, какие бывают типы пользовательских запросов и по каким запросам вы будете продвигать сайт:

 

  • Навигационные (брендовые) запросы — поиск конкретного сайта или места в сети интернет. Обычно по таким запросам сайты находятся на первом месте, и продвижение не нужно.
  • Информационные запросы — поиск информации, неважно на каком сайте (например, как лечиться от простуды).
  • Транзакционные запросы — пользователь хочет совершить какое-то действие («скачать», «купить» и т. д.). Коммерческие запросы всегда являются транзакционными. Но не все транзакционные запросы являются коммерческими (например, «скачать бесплатно»).

 

Коммерческие страницы (интернет-магазины, сайты компаний) нужно продвигать по коммерческим запросам, информационные (форумы, блоги, статьи) — по информационным.

 

48) Определить, каким является запрос, информационным или транзакционным, можно при помощи поиска. Введите фразу и посмотрите на результат поисковой выдачи. Если там в основном информационные статьи, то запрос информационный, если коммерческие страницы — то коммерческий.

 

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

 

50) На одну страницу должен вести один запрос. Можно объединить группы запросов в кластеры. Кластеризация помогает объединить запросы по смыслу и проверить совместимость продвигаемых слов (например, аренда авто, прокат машины). Инструменты для автоматической кластеризации запросов (сервисы платные, но есть бесплатные лимиты):

 

 

51) Структура сайта (меню, навигация) должна определяться только исходя из поискового спроса.

 

52) Для доступа к любой странице с главной должно быть не более трёх кликов.

 

53) Если вы используете хлебные крошки, вместо «Главная» укажите главное ключевое слово. Например, название интернет-магазина.

 

Внутренняя и внешняя оптимизация сайта

 

54) Текст должен быть уникальным (не менее, чем на 70 % в зависимости от тематики). Проверить уникальность текста можно поиском по цитате (запрос в кавычках) или с помощью сервисов:

 

 

55) Длину текста, а также плотность ключевых слов берите из ТОП–10. Проверить можно с помощью инструмента Текстовый анализ от SeoWizard или JustMagic.

 

56) Текст с ключевыми словами размещайте ближе к началу текста.

 

57) Используйте в тексте дополнительные термины и синонимы. Это могут быть подсвечиваемые слова по запросу в поисковой выдаче Яндекса, «Запросы, похожие на» из Яндекс Wordstat.

 

58) Пишите лаконичнее, избегайте стоп-слов. Проверить текст можно в сервисе Главред.

 

59) Пишите без ошибок и внимательно относитесь к оформлению текста. Проверить орфографические ошибки можно при помощи Яндекс.Спеллер.

 

60) Для повышения CTR переходов на сайт из поиска необходимо улучшить его сниппет в поисковой выдаче. Сниппет состоит из:

 

  • заголовка (тег title),
  • описания (в Google — тег description, в Яндексе — часть текста с ключевым словом),
  • структуры URL (хлебные крошки, навигационные цепочки, быстрые ссылки).

 

61) Чтобы улучшить сниппет в Яндексе, возьмите абзац, который показывает Яндекс по ключевому слову в поисковой выдаче, и измените его текст.

 

Разное

 

Переиндексация Яндексом происходит в среднем раз в 2,14 месяца (более 60 дней). SEO — это надолго, нужно уметь ждать. Результаты SEO обычно можно получить через 1–6 месяцев, в зависимости от возраста проекта.

 

Ускорить процесс индексации сайта можно с помощью:

 

  • внешних ссылок,
  • ссылок в социальных сетях (особенно в Twitter),
  • ссылок с главной страницы,
  • через Яндекс.Вебмастер (Индексирование → Переобход страниц).

 

Частота захода бота зависит от частоты обновления сайта.

 

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

 

Очень сложно уместить весь курс в одну статью. Если статья окажется вам полезной, в следующий раз мы напишем о подборе семантического ядра и наращивании ссылочной массы.

 

Если вы хотите самостоятельно разобраться в SEO, рекомендуем пройти курс в Нетологии. Для читателей Хабра у них есть скидка 2500 руб. по промокоду habr на все онлайн-программы (действует до конца 2017 года).