
Требования к реализации.
- Минимальные нововведения на сервере
- Deploy должен быть автоматизирован
- Входная точка для организации deploy — выставления тега для dev сборки и дополнительное ручное подтверждение для prod
- Сборка должна пройти автоматическое тестирование
- Механизм ручной откатки версии
Почему СircleCI?
На проекте с самого начала использовали приватный репозиторий bitbucket. (Сейчас приватные репозитории уже есть в гитхабе.) Не уходя из экосистемы Atlasian решили взять CircleCI (далее CI). Понравилось, что:
- минимальная настройка
- возможность debug по ssh
- бесплатная версия, но с ограничениями
- 2500 кредитов/в неделю (примерно 250 минут выполнения) #go собирается и деплоится быстро, нам хватит
- однопоточное исполнение #у нас не так много pet project
- только lunix и windows #нам нужен linux
Часть первая, workflow
Создадим папку .circle и в ней создадим файл config.yml и опишем там ожидаемый workflow ( порядок исполнения задач)
workflows: version: 2 tagged-build: jobs: - test - dev_deploy: requires: - test - approve_master_deploy: type: approval requires: - test - dev_deploy - prod_deploy: requires: - dev_deploy - approve_master_deploy
Вот результат:

Мы описали паттерн, по которому каждый комит будет сначала проверяться тестами, далее выкатываться на dev, затем при ручном подтверждение отправляться на боевой сервер. Для наведения лоска добавим фильтр, что бы задача срабатывала только по тегу.
- dev_deploy: requires: - test filters: branches: ignore: /.*/ tags: only: /.*/
Второй шаг, самый простой.
Начнем с запуска запуска тестов, тут будет минимум кода.
jobs: test: docker: - image: circleci/golang:1.12 working_directory: ~/go-example/ steps: - checkout # тут будут linter'ы и тд - run: go test -cover -v ./...
После того как наш код протестирован и прошел code style проверки, можно делать deploy на dev. Я предлагаю использоваться для запуска go сервиса supervisor (ver3.1.4 на момент написания статьи), логи будем собирать им же.
Добавим в папку .circleci файлик supervisor_ph.conf, в рамках CI PH_NAME будет меняться на имя проекта. И в такой же файл будем писать вывод логов.
[program:PH_NAME] stopasgroup=true user=deploy-user autostart=true autorestart=true stdout_logfile=/var/log/supervisor/PH_NAME.log stderr_logfile=/var/log/supervisor/PH_NAME.log redirect_stderr=true
Всё, что отличает наш проект от других:

Время Deploy
Для dev и prod изменяются только сервера и к названию приложения добавляется суффикс. Конфиг хранится в переменных окружения. (12 факторные приложения) Эту часть мы вынесем в environment, остальное продублируем.
prod_deploy: environment: TARGET_IP: 0.0.0.0 TARGET_DIR: /var/www/deploy-user/go-example REMOTE_USER: deploy-user SERVICE_NAME: go_example_prod docker: - image: circleci/golang:1.12 working_directory: ~/go-example/ steps: - checkout - add_ssh_keys #копируем добавленные в ci ключи, о них позже - run: go build -ldflags "-X main.version=$CIRCLE_TAG" -o ./main ./src/main - run: ssh -o "StrictHostKeyChecking=no" $REMOTE_USER@$TARGET_IP "mkdir $TARGET_DIR/v$CIRCLE_TAG" #создаем папку по номеру тега, где будут лежать исполняемые и вспомогательные файлы - run: scp main $REMOTE_USER@$TARGET_IP:$TARGET_DIR/v$CIRCLE_TAG/ #загружаем исполняемый файл в директорию по тегу - run: sed "s/PH_NAME/$SERVICE_NAME/g" .circleci/supervisor_ph.conf > .circleci/$SERVICE_NAME.conf - run: echo command=$TARGET_DIR/v$CIRCLE_TAG/main >> .circleci/$SERVICE_NAME.conf - run: scp .circleci/$SERVICE_NAME.conf $REMOTE_USER@$TARGET_IP:$TARGET_DIR/v$CIRCLE_TAG/ - run: ssh $REMOTE_USER@$TARGET_IP "ln -sf $TARGET_DIR/v$CIRCLE_TAG/$SERVICE_NAME.conf /etc/supervisord.d" - run: ssh $REMOTE_USER@$TARGET_IP "supervisorctl -c /etc/supervisord.conf reread && supervisorctl -c /etc/supervisord.conf update" - run: curl "$TELEGRAM_SERVICE?msg=$SERVICE_NAME%20v$CIRCLE_TAG%20deployed&channel=go_deploy"
Для уведомлений мы будем используем собственного бота, который вызывается через curl. Команда `when: on_fail` срабатывает если что-то пошло не так, ее можно также использовать для отката изменений. Хотя у нас это телеграмм бот, но в целом можно обойтись без него и использовать стандартные нотификации: Slack,IRC. Плюс уведомления об ошибках уходят на email.
Переменную `$TELEGRAM_SERVICE` добавим через раздел BUILD SETTINGS→Environment Variables.
- run: command: curl "$TELEGRAM_SERVICE?msg=$SERVICE_NAME%20v$CIRCLE_TAG%20failed&channel=go_deploy" when: on_fail
Финишная прямая
Делаем push в github или в bitbucket. После идем в CircleCI в пункт Add project

Затем выбираем Start building. Финальным шагом будет добавления ssh ключа для авторизации на сервере под выбранным пользователем.

Всё можно делать deploy, ставим tag и начинаем радоваться жизни. Финальный вариант ./.circleci/config.yml — тут
ссылка на оригинал статьи https://habr.com/ru/post/485240/
Добавить комментарий