8

我将使用 GitLab CI 服务器部署简单的 Spring Boot 应用程序。我.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]

但是,我无法加载应用程序,因为一旦跑步者完成阶段,服务就停止了:

$ 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 启动脚本、GitLab 配置、我的服务脚本或其他什么?

我正在使用 GitLab CI 多运行器版本 0.5.0 (c38415a) 运行 Ubuntu 14.04。

升级版:

将运行器升级到版本 1.0.1 (cffb5c7) 并不能解决问题。

4

2 回答 2

17

为什么这样做是个坏主意...

正如其文档中明确指出的那样,GitLab Runner “运行测试并将结果发送到 GitLab”。

并且由于测试应该及时启动和停止,运行程序旨在在完成每个构建后终止所有创建的进程。

所以你的服务被杀死不是一个错误,它是一个特性。;)


GitLab CI 文档建议使用 dpl进行部署

dpl 是一个项目,可让您在各种 PaaS 提供商处部署您的应用程序,例如 Google App Engine、Heroku 或 Elastic Beanstalk。

因此,它会向某些 REST API 发出一些请求或通过互联网推送一些其他数据,并且它的进程很好地退出。


所以做你想做的事实际上需要一些黑客行为——覆盖默认的跑步者行为。而且您不应该将其作为长期解决方案,因为它可能会因某些 runner/gitlab 更新而停止工作。

...但是如果您坚持,那么这里是操作方法:)

在您的情况下,当您想在跑步者的主机上实际部署和运行应用程序时,我们需要使用两个技巧:

好的,这里是说明:

  1. 确保您可以使用 SSH 私钥从运行器主机 SSH 到它自己/root/.ssh/id_rsa,无需密码,无需确认指纹。ssh localhostrun byroot应该以非交互方式工作。

  2. 编辑你的 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"
    

(运行器会在保存配置文件后重新加载)

  1. 编辑您的服务脚本,使其创建的进程不会是 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
    

通过重试上次构建或提交到您的项目存储库进行测试。


PS 我使用如下所示的初始化脚本测试了我的解决方案:

#!/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 "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  *)
    echo $"Use this options $0 {start|stop}"
    exit 1
esac

..在带有 gitlab-multi-runner v. 1.02 和 GitLab CE 8.5.0 的 Ubuntu 14.04 上。

于 2016-02-04T19:54:51.790 回答
0

虽然@GregDubicki 发布的解决方案非常完美,并且包含对每个步骤的解释,但我最终得到了一个带有监控服务的解决方案,它在每次构建后重新启动我的服务。

这种方法具有以下优点:

  1. 你不应该在root用户下启动跑步者
  2. 你不应该关心被跑步者杀死的进程
  3. (+ 奖励)你现在有一个监控系统!
于 2016-02-05T17:16:46.147 回答