Простой деплой сайта на хостинг из Git-репозитория
Давным-давно я заливал сайты в интернет с помощью FTP-клиента. Потом интернет стал быстрее, и я стал прямо по FTP править странички, потому что каждый раз вручную копировать файлы было жутко неудобно.
Сейчас код всех моих сайтов находится в гит-репозиториях на Гитхабе или Битбакете, поэтому можно легко организовать выкладку сайтов оттуда: внесли изменения, закоммитили код, набрали команду в консоли, и через минуту пользователи уже видят новую версию сайта.
Для этого я использую свой шелл-скрипт shipit: он позволяет выполнять любые команды на сервере по SSH. До этого я долго использовал Fabric, но Шипит проще и удобнее.
Настройка авторизации
Для начала нужно настроить авторизацию с помощью SSH-ключей: без паролей и смс.
Создание SSH-ключа и добавление его на Гитхаб или Битбакет
Создание и использование ключей хорошо описано в документации Гитхаба и Битбакета. Это нужно сделать и на локальном компьютере, и на хостинге, чтобы он тоже мог ходить на Гитхаб или Битбакет.
Создание псевдонима соединения
Чтобы не набирать каждый раз имя хоста и логин, можно создать псевдоним. Для этого добавим в файл ~/.ssh/config
:
Host myhost
HostName 113.113.13.13
User tema
IdentityFile ~/.ssh/id_rsa
Замените данные на ваш хост, логин и ключ, созданный в предыдущем шаге.
Загрузка SSH-ключа на хостинг
Избавимся от необходимости вводить пароль при каждом заходе:
ssh myhost 'mkdir -p .ssh && cat >> ~/.ssh/authorized_keys' < ~/.ssh/id_rsa.pub
Теперь вы можете заходить на хостинг набирая:
ssh myhost
Подготовка проекта
Для сборки я использую Грант. Если вы не используете Грант, можете пропустить этот раздел.
Есть два способа сборки и деплоя сайта:
- Коммитить собранные файлы, деплоить простым
git pull
. - Коммитить только исходный код, собирать при деплое.
Я обычно использую второй. Репозиторий получается аккуратнее, диффы чище, работать удобнее. Но приходится настраивать на сервере сборку. Однако с Грантом это не проблема.
Для деплоя я создаю специальную задачу deploy
, где нет оптимизации картинок, тестирования и других долгих задач, не имеющих значения при сборке сайта.
grunt.registerTask('default', [
'jshint',
'concat',
'stylus',
'imagemin'
]);
grunt.registerTask('deploy', ['concat', 'stylus']);
Плагины для Гранта я всегда устанавливаю с ключом --save-dev
, чтобы сохранять ссылки на их конкретные версии в package.json
. Он должен выглядеть примерно так:
{
"name": "example",
"version": "0.0.0",
"private": true,
"devDependencies": {
"grunt": "~0.4.2",
"load-grunt-tasks": "~0.2.0",
"grunt-contrib-jshint": "~0.7.2",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-stylus": "~0.11.0",
"grunt-contrib-imagemin": "~0.4.0"
}
}
Так я могу быть уверен, что сборка не сломается
Подготовка репозитория
Добавим в локальный репозиторий ссылку на удалённый (на Гитхабе или Битбакете) и запушим код:
git remote add origin git@github.com:sapegin/example.git
git push -u origin master
Клонирование репозитория на хостинг
Клонируем репозиторий сайта на хостинг:
ssh myhost
git clone git@github.com:sapegin/example.git ~/sites/example.com
logout
Никаких паролей запрашиваться уже не должно.
Установка shipit
Шипит устанавливается одной строкой:
pathtoshipit=/usr/local/bin/shipit; curl -o $pathtoshipit https://raw.github.com/sapegin/shipit/master/bin/shipit; chmod +x $pathtoshipit; unset pathtoshipit
Настройка деплоя
Типичный скрипт деплоя у меня выглядит так:
git checkout master
git pull
npm install
node -e "require('grunt').cli()" _ deploy
Переведу на русский язык:
- Переходим в ветку
master
(на всякий случай). - Получаем свежий код с Гитхаба/Битбакета.
- Устанавливаем/обновляем npm-пакеты.
- Запускам сборку Грантом.
Последний пункт нужно пояснить: я запускаю задачу deploy
локально установленным (npm install
без ключа -g
) Грантом. Так всё нужное для деплоя (кроме Гита и npm) устанавливается одной командой npm install
и не требует sudo
.
Напишем скрипт для Шипита:
host='myhost'
path='sites/example.com'
[deploy]
git checkout master
git pull
npm install
node -e "require('grunt').cli()" _ deploy
И сохраним его как .shipit
в папке проекта.
Шипит работает очень просто: он подключается к серверу по SSH, переходит в папку сайта и выполняет там команды, указанные после метки [deploy]
. (На самом деле возможностей у него больше.)
Всё, теперь можно разложить сайт одной командой, не считая коммита и пуша изменений:
git commit -a -m "Make ponies pink."
git push
shipit