How to start a service using a GitLab runner and prevent it from stopping?

I am going to deploy a simple Spring application to boot using the GitLab CI server. My .gitlab-ci.yml looks like this:

 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 

And the deploy stage produces the following output:

 $ 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] 

However, I cannot download the application because the service was stopped after the runner finished the stage:

 $ service gitlab-runner-test status Not running (process 21177 not found) 

My service scripts delegate the actual work to the compiled war package:

 #!/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 $* 

In addition, when I start the service with my hands ( service gitlab-runner-test start ), it remains on even after the user session is closed.

I'm not sure what the root of the problem is - Spring Startup script download, GitLab configuration, my utility scripts or something else?

I am running Ubuntu 14.04 with GitLab CI multi runner version 0.5.0 (c38415a).

UPD:

Updating the runner to version 1.0.1 (cffb5c7) does not solve the problem.

+6
source share
2 answers

Why is this a bad idea?

As its documentation says, GitLab Runner runs tests and sends the results to GitLab. "

And since the tests must start and stop in a timely manner, the runner is designed to destroy all created processes after the completion of each assembly.

So it’s not a mistake that your service is killed, this is a feature .;)


GitLab CI Documentation recommends using dpl for deployment .

dpl is a project that allows you to deploy your application to various PaaS providers, such as Google App Engine, Heroku, or Elastic Beanstalk.

Thus, it calls some requests to some REST APIs or pushes other data over the Internet, and its process finishes perfectly.


So doing what you want to do requires some hacking - overriding the default behavior for runners. And you should not do this as a long-term solution, because it may stop working with some runner / gitlab update.

... but if you insist, then here's how to do it :)

In your case, when you want to actually deploy and run the application on your runner host, we need to use two hacks:

  • do not use the default shell executable ssh , but ssh and make the ssh executor itself (inspired by michael 's solution to this question (please refrain his answer too if you are mine!),
  • edit the process that starts using the script solution ( Joe for this question (again - please raise it!)

So here are the instructions:

  • Make sure you can use SSH from your leader host using the SSH private key in /root/.ssh/id_rsa , without passphrase, without fingerprint confirmation. ssh localhost run by root should not work interactively.

  • Modify the gitlab-runner configuration file, /etc/gitlab-runner/config.toml so that it looks like this:

     [[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" 

(The runner will reboot after saving the configuration file)

  1. Edit the script service so that the process it creates is NOT a child of the init script, and it will not open stdin, stdout and 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 

Testing by reassembling the last build or fixing your project repo.


PS I tested my solution with an init script that looks like this:

 #!/usr/bin/env bash start() { # Completely disowned process, not a child # Credits: Joe at /questions/447838/how-can-i-launch-a-new-process-that-is-not-a-child-of-the-original-process/1961541#1961541 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 

.. on Ubuntu 14.04 with gitlab-multi-runner v. 1.02 and GitLab CE 8.5.0.

+9
source

While the solution posted by @GregDubicki works great and contains explanations for each step, I ended up getting a recommendation with a monitoring service that restarts my service after each build.

This approach has the following advantages:

  • You can not run the runner as root user
  • You do not need to care about the processes killed by the runner
  • (+ bonus) Now you have a monitoring system!
-1
source

All Articles