Как запустить службу с помощью GitLab runner и предотвратить ее остановку?
Я собираюсь развернуть простое приложение Spring Boot с помощью сервера GitLab CI. Мой .gitlab-ci.yml
следующим образом:
stages:
- build_and_test
- deploy
web_server_build_and_test:
stage: build_and_test
script:
- mvn clean package
web_server_deploy:
stage: deploy
script:
- mvn clean package -Pprod
- service gitlab-runner-test stop
- cp target/*.war /var/gitlab-runner-test/gitlab-runner-test.war
- chmod +x /var/gitlab-runner-test/gitlab-runner-test.war
- service gitlab-runner-test start
и deploy
этап производит следующий вывод:
$ service gitlab-runner-test stop
Stopped [13247]
$ cp target/*.war /var/gitlab-runner-test/gitlab-runner-test.war
$ chmod +x /var/gitlab-runner-test/gitlab-runner-test.war
$ service gitlab-runner-test start
Started [21177]
однако я не могу загрузить приложение, так как служба была остановлена, как только runner завершает этап:
$ service gitlab-runner-test status
Not running (process 21177 not found)
мои сценарии обслуживания делегируют фактическую работу собранному war
пакет:
#!/usr/bin/env bash
export JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre/bin/java
export MODE=service
export APP_NAME=gitlab-runner-test
export PID_FOLDER=/var/run/gitlab-runner-test
/var/gitlab-runner-test/gitlab-runner-test.war $*
кроме того, когда я начинаю обслуживания руками (service gitlab-runner-test start
) он остается запущенным даже после закрытия сеанса пользователя.
Я не уверен, в чем корень проблемы - Spring Boot startup script, конфигурация GitLab, мои сценарии обслуживания или что-то еще?
Я запускаю Ubuntu 14.04 с GitLab CI multi runner версии 0.5.0 (c38415a).
UPD:
обновление runner до версии 1.0.1 (cffb5c7) не решает проблему.
2 ответов
почему это плохая идея, чтобы сделать это...
как четко указано в его документации,GitLab Runner "трассы тесты и отправляет результаты в GitLab".
и поскольку тесты должны запускаться и останавливаться своевременно, runner предназначен для уничтожения всех созданных процессов после завершения каждой сборки.
так это не ошибка что ваша служба убита, это характеристика. ;)
документация GitLab CI рекомендует использовать dpl на развертывание.
dpl-это проект, который позволяет развертывать приложение в различных провайдерах PaaS, таких как Google App Engine, Heroku или Elastic Beanstalk.
таким образом, он запускает некоторые запросы к некоторым API REST или проталкивает некоторые другие данные через интернеты, и его процесс красиво завершается.
так выполнение того, что вы хотите сделать, на самом деле требует некоторого взлома - переопределения поведения бегуна по умолчанию. И вы не должны делать это как долгосрочное решение, потому что оно может перестать работать с некоторым обновлением runner/gitlab.
...но если вы настаиваете, то вот как :)
в вашем случае, когда вы хотите фактически развернуть и запустить приложение на хосте вашего бегуна, нам нужно использовать два Хака:
- не используйте значение по умолчанию
shell
runner исполнитель, ноssh
и сделать исполнитель ssh для себя (вдохновленный решение Майкла на этот вопрос (пожалуйста, upvote его ответ тоже, если upvoting мой!), - откреститься от процесса запуска скриптов init (решение Джо этого вопроса (еще раз-пожалуйста, upvote его!)
хорошо, вот инструкции:
убедитесь, что вы можете SSH от вашего хоста runner к себе с закрытым ключом SSH в
/root/.ssh/id_rsa
, без парольной фразы, без подтверждения отпечатка пальца.ssh localhost
run byroot
должен работать неинтерактивно.-
отредактируйте конфигурационный файл GitLab-runner,
/etc/gitlab-runner/config.toml
чтобы это выглядело так:[[runners]] name = "your-runner-name" url = "https://<your_gitlab_instance_fqdn>/ci" token = "<your_project_CI_token>" tls-ca-file = "" executor = "ssh" [runners.ssh] user = "root" password = "" host = "localhost" port = "22" identity_file = "/root/.ssh/id_rsa"
(runner перезагрузится после сохранения файла конфигурации)
-
отредактируйте свой скрипт службы, чтобы процесс, который он создаст, не был дочерним скриптом init и не открывался stdin, stdout и stderr:
#!/usr/bin/env bash export JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre/bin/java export MODE=service export APP_NAME=gitlab-runner-test export PID_FOLDER=/var/run/gitlab-runner-test /var/gitlab-runner-test/gitlab-runner-test.war $* <&- >&- 2>&- & disown
Test, повторив последнюю сборку или сделав фиксацию в репо проекта.
PS Я тестировал свое решение с помощью сценария init, который выглядел так:
#!/usr/bin/env bash
start() {
# Completely disowned process, not a child
# Credits: Joe at https://stackoverflow.com/a/26420299/2693875
sleep 99999 <&- >&- 2>&- & disown
exit 0
}
stop() {
echo "doing nothing"
exit 0
}
echo "running on $HOSTNAME..."
case "" in
start)
start
;;
stop)
stop
;;
*)
echo $"Use this options {start|stop}"
exit 1
esac
..на Ubuntu 14.04 с GitLab-multi-runner V. 1.02 и GitLab CE 8.5.0.
в то время как решение, опубликованное @GregDubicki, работает просто отлично и содержит объяснения для каждого шага, у меня есть solition со службой мониторинга, которая перезапускает мою службу после каждой сборки.
этот подход имеет следующие преимущества:
- вы не должны запускать runner под
root
пользователей - вы не должны заботиться о процессах, убитых runner
- (+бонус) теперь у вас есть система мониторинга!