Search code examples
dockerdocker-composegitlabcypressgitlab-ci

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


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???


Solution

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