skip to Main Content

I have this GitLab CI/CD:

stages:
  - test

variables:
    DOCKER_DRIVER: overlay2
    DOCKER_TLS_CERTDIR: ""
    DOCKER_HOST: tcp://docker:2375

integration_test:
  image: cypress/base
  stage: test
  services:
    - docker:dind
  before_script:
    - apt-get update && apt-get install -y curl iproute2
    - export RUNNER_IP=$(ip addr show eth0 | grep -Po 'inet K[d.]+') && echo $RUNNER_IP
    - curl -fsSL https://get.docker.com | sh
    - docker --version
    - docker login -u TOKEN -p TOKEN registry.gitlab.com
    - docker pull registry.gitlab.com/a.bovi-work/tests-template/service-a:latest
    - docker pull registry.gitlab.com/a.bovi-work/tests-template/service-b:latest
  script:
    - docker compose up -d
    - sleep 10 # Wait for the services to start
    - docker ps
    - curl http://${RUNNER_IP}:8082/hello
    - npm install
    - npx cypress run --spec cypress/integration/serviceb_that_calls_servicea.js --config baseUrl=http://${RUNNER_IP}:8082
    - docker compose down

and this docker-compose.yaml:

services:

  service-a:
    image: registry.gitlab.com/a.bovi-work/tests-template/service-a:latest
    ports:
      - 8080:8080

  service-b:
    image: registry.gitlab.com/a.bovi-work/tests-template/service-b:latest
    environment:
      - quarkus.rest-client.service-a.url=http://service-a:8080
    ports:
      - 8082:8082

whit this cypress.config.js:

// cypress.config.js
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    specPattern: "cypress/integration/**/*.js",
    baseUrl: "http://localhost:8082",
    supportFile: false
  }
})

and this test:

describe('Service B Hello Endpoint', () => {
    it('should fetch data and verify the response', () => {
        cy.request({
            method: 'GET',
            url: '/hello'
        })
            .then((response) => {
                // Assertions
                expect(response.status).to.eq(200);
                expect(response.headers['content-type']).to.include('application/json');
                expect(response.body).to.eq('Hello from Service B, that called Service A too: Hello from Service A');
            });
    });
});

but this happens:

$ docker compose up -d
 Network e2e_default  Creating
 Network e2e_default  Created
 Container e2e-service-a-1  Creating
 Container e2e-service-b-1  Creating
 Container e2e-service-b-1  Created
 Container e2e-service-a-1  Created
 Container e2e-service-a-1  Starting
 Container e2e-service-b-1  Starting
 Container e2e-service-b-1  Started
 Container e2e-service-a-1  Started
$ sleep 10
$ docker ps
CONTAINER ID   IMAGE                                                             COMMAND                  CREATED          STATUS          PORTS                                       NAMES
19b9c017e9b3   registry.gitlab.com/a.bovi-work/tests-template/service-a:latest   "java -jar /app/quar…"   15 seconds ago   Up 10 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   e2e-service-a-1
9ee49bdd07b6   registry.gitlab.com/a.bovi-work/tests-template/service-b:latest   "java -jar /app/quar…"   15 seconds ago   Up 10 seconds   0.0.0.0:8082->8082/tcp, :::8082->8082/tcp   e2e-service-b-1
$ curl http://${RUNNER_IP}:8082/hello
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
curl: (7) Failed to connect to 172.17.0.4 port 8082: Connection refused

P.S.: I’m trying to use CURL for testing purposes, because cypress can’t connect to baseUrl=http://${RUNNER_IP}:8082.

How can I connect to a service that is UP from docker compose inside the GitLab CI/CD???

3

Answers


  1. Chosen as BEST ANSWER

    I found an alternative.

    With this docker-compose.yml:

    services:
    
      service-a:
        image: registry.gitlab.com/a.bovi-work/tests-template/service-a:latest
        ports:
          - 8081:8080
    
      service-b:
        image: registry.gitlab.com/a.bovi-work/tests-template/service-b:latest
        environment:
          - quarkus.rest-client.service-a.url=http://service-a:8080
        ports:
          - 8082:8082
        depends_on:
          - service-a
    
      cypress:
        image: cypress/base
        volumes:
          - ./cypress:/e2e/cypress
          - ./package.json:/e2e/package.json
          - ./cypress.config.js:/e2e/cypress.config.js
          - ./reports:/e2e/cypress/reports
        environment:
          - CYPRESS_baseUrl=http://service-b:8082
        depends_on:
          - service-b
        working_dir: /e2e
        command: >
          sh -c "npm install && npx cypress run --spec ./cypress/integration/serviceb_that_calls_servicea.js"
        user: root  # Required to run Cypress in the container
    
    

    And this GitLab CI/CD:

    stages:
      - test
    
    integration_test:
      image: docker
      stage: test
      services:
        - docker:26-dind
      before_script:
        - docker --version
        - docker login -u TOKEN -p TOKEN registry.gitlab.com
        - docker pull registry.gitlab.com/a.bovi-work/tests-template/service-a:latest
        - docker pull registry.gitlab.com/a.bovi-work/tests-template/service-b:latest
      script:
        - rm -rf ./reports/*
        - docker compose up --abort-on-container-exit --exit-code-from cypress
      artifacts:
        paths:
          - ./reports
        reports:
          junit: ./reports/junit-*.xml
        expire_in: "30 days"
    

  2. I believe you are using an incorrect approach here. You should not be creating two additional containers with dind. Intead, gitlab already has a thing called Services available in the pipeline.

    If your gitlab-ci.yml belongs to your group somewhere in gitlab.com/a.bovi-work, then you can set gitlab itself (look in the repo settings) to allow login-less pulling of your images.

    Next, you can set up environmental variables for your services (see line 9 of the example below)

    And finally, just use http://service-b:8082 instead of http://${RUNNER_IP}:8082 when running cypress. May be service-a, maybe I’m just failing to grasp the connection between the two containers.

    In any case, this is untested, but should work. Just simply experiment a bit and see what suits you best.

    Here’s the full example I cooked up:

    integration_test:
      image: cypress/base
      stage: test
      services:
        - name: registry.gitlab.com/a.bovi-work/tests-template/service-a:latest
          alias: service-a
        - name: registry.gitlab.com/a.bovi-work/tests-template/service-b:latest
          alias: service-b
          variables:
            quarkus.rest-client.service-a.url: "http://service-a:8080"
      script:
        - npm install
        - npx cypress run --spec cypress/integration/serviceb_that_calls_servicea.js --config baseUrl=http://service-b:8082
    

    References:

    Login or Signup to reply.
  3. The containers are running in diod container.

    To connect to them connect with docker:8081 ip and port, not runner ip.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search