Search code examples
gitlab-ciintegration

How to run a service only once and use it in multiple jobs


This is my use case:

I have a service that is very slow to start, so it is not practical to start it in every test case. I have ~20 test suites to run on that service. I want to divide them in their independent jobs, so that they can be rerun in isolation if one fails.

So, I want to start the service in one previous job to the test stage, then use it throughout the test stage. Is this possible?

I expected gitlab to have some option to create a service that can be added into the job, something like this:

job: 
   script:
      - service start
      - echo "Service started"

test:
   services:
      - job
   script:
      - test on job:8080

Solution

  • No, services: are tied to the lifecycle of the job. Service containers can't be persisted across jobs.


    This probably isn't practical for the use case you've described, but there is a workaround that is perhaps worth mentioning for other readers with different use-cases...

    On self-hosted docker runners, you can configure something similar using container links with containers managed on the host. This can be done using the links parameter in the [runners.docker] section of the runner configuration. That is to say: you can run a container on the runner host and automatically link that container to all jobs for the runner, similar to how services are linked per job. However, the runner will not manage the container for you, so actions like starting or stopping the container or managing concurrent access will have to be done yourself.

    For example, on my runner host, I can start a container that will be persistent and link it to all jobs on the runner.

    First, start the container on the runner host. In this case, a simple HTTP service:

    docker run -d \
               --name=my_container \
               -p 80 \
               strm/helloworld-http:latest
    

    Then in the runner config.toml I would configure the links parameter:

    # ...
    [runners.docker]
    # ...
    links = ["my_container:my-service-hostname"]
    

    Then in all jobs on this runner, I should be able to access the container:

    myjob:
      script:
        - curl http://my-service-hostname