Travis CI для автоматизации сборки статичного сайта

Для запуска сборки статического сайта совершенно не обязательно использовать свой компьютер или выделенный сервер. Достаточно воспользоваться сервисом Continuous integration (CI). Одним из представителей которых является Travis CI.

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

Для управления процесом сборки используется файл .travis.yml, который располагается в корневой директории репозитория. именно в нем определяется, какой язык програмирования будет использоваться для сборки, в каком окружении будет работать сборщик и какие команды требуется выполнить. Документация по формату данного файла довольно обширная, и лучше обратиться в официальную документацию сервиса для получения подробной информации. Я же остановлюсь только на вопросах сборки сайта с использованием Jekyll и последующим его деплоем.

Сборка

Для использования Jekyll используется язык программирования Ruby и при этом для ускорения сборки при использовании LSI нужно еще дополнительно установить библиотеки gsl. Для этого достаточно использовать следующий файл .travis.yml:

rvm:
  - 2.1

cache:
  - apt
  - bundler

addons:
  apt:
    packages:
      - libgsl0-dev

script: bundle exec rake build

after_success: bundle exec rake deploy

branches:
  only:
    - master

Первый блок указывает на использование RVM версии 2.1, следующий блок активирует использование кеша для ускорения сборки. Блок addons используется в данном случае для установки дополнительного пакета libgsl0-dev, который будет использоваться при установке gem. В блоках script и after_success указаны команды, которые используются для сборки и соответственно деплоя (обе задачи определяются в Rakefile проекта). И самый последний блок используется для указания того, что сборка запускается только при комите в основную ветку разработки.

Использование кеша зависимостей и установленной gsl-библиотеки позволило мне при активированном LSI сократить время сборки и деплоя до менее чем полутора минут. Отличный результат!

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

Деплой

Travis-CI поддерживает очень большое число сервисов для деплоя (полный список). И плюс к этому можно определять свои правила.

Я протестировал три варианта:

  1. Деплой на Amazon S3 средствами Travis.
  2. Деплой на Amazon S3 с использованием s3_website.
  3. Деплой на свой сервер с использованием Rsync.

Для того, чтобы авторизоваться в сервисах, необходимо использовать либо свои учетные данные, либо ssh-ключи. Выкладывать их в открытый доступ нет совершенно никакого смысла. Поэтому для решения данной проблемы в Travis используется шифрование с ключом (описание), который генерируется для каждого репозитория отдельно.

И если для использования деплоя в S3 требуется только определить переменные со своими учетными данными, то с ключами требуется еще прописать ряд команд:

addons:
  ssh_known_hosts:
  - git.example.com
  - 111.22.33.44

before_install:
  - openssl aes-256-cbc -K $encrypted_964109d0fde0_key -iv $encrypted_964109d0fde0_iv
    -in travis.id_rsa.enc -out $HOME/.ssh/id_rsa -d
  - chmod 600 $HOME/.ssh/id_rsa
  - eval "$(ssh-agent -s)"
  - ssh-add $HOME/.ssh/id_rsa

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

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

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

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

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

rsync -qavz public/* temp@176.52.134.25:~/public/

При использовании деплоя на сервера Амазона попробовал использовать решение от Travis, но остался недоволен, так как оно ориентировано на загрузку результатов компиляции и не ориентировано на загрузку большого числа небольших по размеру файлов или задания нестандартных правил кеширования. В итоге загрузка моего сайта заняла более 8 минут и при этом файлы были не сжаты и без заголовков кеширования. Для размещения сайта использовать решение Travis не имеет смысла.

И попробовал использовать s3_website, которое позволяет очень тонко настраивать различные параметры сайта, и при этом имеет очень высокую скорость загрузки файлов на сервера амазона. В итоге остался более чем доволен, файлы загружаются сжатыми, для различных типов файлов задаются свои правила кеширования. Есть возможность задавать редиректы. По использованию данного решения отправляю на страницу проекта.

Почти сутки потратил на тестирование различных вариантов размещения сайта с использованием Travis. Было много ошибок, и много находок. В итоге осознал, что теперь мне не нужен сервер для того, чтобы генерировать и хостить свой сайт. Произвел его перенос в Amazon S3. Генерацию перенес на Travis. И теперь уже без своего сервера имею возможность комитить и получить на выходе рабочий сайт.

Была мысль использовать CloudFront, как уже делаю для своей визитки denis.evsyukov.org. Но при использовании обновляемого сайта это оказалось неудобным, так как на инвалидацию объектов кеша уходит довольно много времени.

Так же вернулся на использование Amazon Route53 для управления своей доменной зоной. По стоимости выходит чуть более $0.5 в месяц за одну зону, но имеет гораздо более гибкие настройки, и при этом есть возможность каждые 30 секунд проверять сайт на работоспособность. И в случае возникновения проблем, сообщать об этом письмом. На мой взгляд это небольшие деньги за такие возможности.