# Travis: Deploy over SSH

Во время [миграции](https://www.juev.org/2016/09/01/vps/ "Миграция сайта с CloudFront на DigitalOcean") сайта на свой собственный сервер у меня было две возможности:

1. Настроить webhook на самом сервере для генерации запуска сборки сайта непосредственно на сервере после каждого комита.
1. Продолжать использовать для генерации сайта сервис Travis-CI, но тут возникает сложность при публикации результата.

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

В итоге уже имеем готовую инфраструктуру для генерации сайта, и остается лишь настроить вебсервер и продумать каким образом передавать файлы с сервера Travis на наш веб-сервер.

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

Предлагаемое решение подразумевает хранение SSH-ключей непосредственно в репозитории проекта. То есть в общедоступном и небезопасном месте. Таким образом нашей задачей становятся подготовка ограниченного окружения на сервере, к которому будет иметь доступ Travis, и шифрование ключей для хранения в репозитории.

Создание нового пользователя и выдачу ему прав описывать не буду, здесь все тривиально и ничего особенного нет. Единственно, нужно обратить внимание на создание новых SSH-ключей для нового пользователя, создавать будем ключ типа RSA (пробовал использовать ed25519, но возникли проблемы с его использованием на сервере Travis). Переходим в директорию репозитория и используем команды:

```shell
ssh-keygen -t rsa -b 4096 -C '<repo>@travis-ci.org' -f ./deploy_rsa
travis encrypt-file deploy_rsa --add
ssh-copy-id -i deploy_rsa.pub <ssh-user>@<deploy-host>
```

Первая команда генерирует ключи в текущей директории (ВАЖНО: не задавайте пароль), вторая команда шифрует приватный ключ и прописывает его использование в файл `.travis.yml`, а третья команда загружает публичный ключ на наш сервер. Не забудьте указать определенные значения вместо переменных repo, ssh-user и deploy-host.

Теперь удаляем подготовленные ключи и добавляем под контроль зашифрованный файл:

```shell
rm -f deploy_rsa deploy_rsa.pub
git add deploy_rsa.enc
```

Остается немного поправить файл конфигурации `.travis.yml`. После шифрования файла уже будут добавлены строки:

```yaml
 - openssl aes-256-cbc -K $encrypted_d7becb892f62_key -iv $encrypted_d7becb892f62_iv
   -in deploy_rsa.enc -out $TRAVIS_BUILD_DIR/deploy_rsa -d
 ```

Нужно только в параметре out добавить переменную `$TRAVIS_BUILD_DIR`. И затем нужно добавить определение дополнения ssh\_known\_hosts:

```yaml
addons:
   ssh_known_hosts: <deploy-host>
```

Как и ранее, не забудьте поменять переменную deploy-host на ip-адрес или доменное имя своего сервера, в зависимости от того, что вы будете использовать в команде rsync.

И теперь осталось только прописать команды по инициализации нового ключа:

```yaml
after_success:
 - eval "$(ssh-agent -s)"
 - chmod 600 $TRAVIS_BUILD_DIR/deploy_rsa
 - ssh-add $TRAVIS_BUILD_DIR/deploy_rsa
 - bundle exec rake publish
 ```

Загрузка файлов на сервер осуществляется только в том случае, если генерация сайта прошла успешно, поэтому все команды прописываются в блоке after\_success. Первые три команды осуществляют запуск ssh-агента, установку верных прав доступа для ключа и добавление ключа в уже работающий агент. И последняя команда используется для запуска самого деплоя. Так как в моем случае производиться не только деплой, но так же оповещение поисковых систем об изменениях, запускается задача из Rakefile.

Для передачи файлов используется следующая команда:

```shell
rsync -az --delete-after $TRAVIS_BUILD_DIR/public/ <ssh-user>@<deploy-host>:<directory>
```

Текущую версию файла конфигурации Travis можно найти в моем репозитории: [.travis.yml](https://raw.githubusercontent.com/Juev/juev.org/2ce4697c24bf4f52da04dc2f0a1c5ad03a92119a/.travis.yml).

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

