Search code examples
gitlabgitlab-cieventstoredb

Unable to connect to container in Gitlab CI in my free account


I have a free account of gitlab. I also have a company account (not sure which plan).

I have the exact same project, a wrapper on EventStore.

In the CI pipeline I want to spin up a container with event store so that I can run some integration tests against it.

This is my .gitlab-ci.yml that restores, compiles, runs tests and publishes nuget packages

#Stages
stages:
  - ci
  - pack

#Global variables
variables:
  GITLAB_RUNNER_DOTNET_CORE: mcr.microsoft.com/dotnet/core/sdk:2.2
  EVENT_STORE: eventstore/eventstore:release-5.0.2
  NUGET_REPOSITORY: $NEXUS_NUGET_REPOSITORY
  NUGET_API_KEY: $NEXUS_API_KEY
  NUGET_FOLDER_NAME: nupkgs

#Docker image
image: $GITLAB_RUNNER_DOTNET_CORE

#Jobs
ci:
  stage: ci
  services:
    - $EVENT_STORE
  variables:
    # event store service params testing with standard ports
    EVENTSTORE_INT_TCP_PORT: "1113"
    EVENTSTORE_EXT_TCP_PORT: "1113"
    EVENTSTORE_INT_HTTP_PORT: "2113"
    EVENTSTORE_EXT_HTTP_PORT: "2113"
    EVENTSTORE_EXT_HTTP_PREFIXES: "http://*:2113/"   
  script:
    - dotnet restore --no-cache --force
    - dotnet build --configuration Release
    - dotnet vstest test/*Tests/bin/Release/**/*Tests.dll

pack-beta-nuget:
  stage: pack
  script:
    - export VERSION_SUFFIX=beta$CI_PIPELINE_ID
    - dotnet pack *.sln --configuration Release --output $NUGET_FOLDER_NAME --version-suffix $VERSION_SUFFIX --include-source --include-symbols -p:SymbolPackageFormat=snupkg
    - dotnet nuget push **/*.nupkg --api-key $NUGET_API_KEY --source $NUGET_REPOSITORY
  except:
    - master

pack-nuget:
  stage: pack
  script:
    - dotnet restore
    - dotnet pack *.sln --configuration Release --output $NUGET_FOLDER_NAME
    - dotnet nuget push **/*.nupkg --api-key $NUGET_API_KEY --source $NUGET_REPOSITORY
  only:
    - master

As you can see, I spin up the event store container.

From my integration tests I try to connect to the container within the CI using the following connection string: "ConnectTo=tcp://admin:changeit@127.0.0.1:1113; HeartBeatTimeout=500;";

With my work account it works fine, there is a container listening on 127.0.0.1 on port 1113 and I can connect to it using the above connection string.

With my free personal account it is unable to connect.

Why?

I suspect it has something to do with the way docker is available on both gitlab CI runners, but why is different?

And more important, how can I configure event store on my personal CI pipeline on my free account so that I can connect to it if the localhost is not a valid host Uri for whatever reason?


Solution

  • Well, you have not provided any details but it seems you're using the Docker executor. In that case, services are not available on localhost but only accessible as service aliases.

    This is an extract from the working CI file:

    test:
      stage: test
      script:
        - dotnet test
      variables:
        ASPNETCORE_ENVIRONMENT: Testing
        EVENTSTORE_EXT_HTTP_PORT: 2113
        EVENTSTORE_EXT_TCP_PORT: 1113
        EVENTSTORE_RUN_PROJECTIONS: all
        EVENTSTORE_START_STANDARD_PROJECTIONS: "true"
        EventStore__ConnectionString: ConnectTo=tcp://admin:changeit@eventstore:1113
      services:
        - name: eventstore/eventstore:latest
          alias: eventstore
      only:
        refs:
          - branches
          - tags
    

    For this to work, your appsettings.Testing.json file needs to point to ConnectTo=tcp://admin:changeit@eventstore:1113.

    If you want to keep using the appsettings file with the configuration that points to localhost, you can override the setting using env variable in the CI file. Just remember to add environment variables as the configuration source. The code snippet above has such an override, matching our settings structure:

    {
      "EventStore": {
        "ConnectionString": "ConnectTo=whatever"
      }
    }
    

    If you ever decide using the Kubernetes executor, you will need to revert to using localhost, because Kubernetes executor creates one pod per build with multiple containers, including all service containers. There's an open issue to support service aliases with Kubernetes runners, I think it will be like 12.9 or 13, pretty soon. That being said, using service aliases is a safe, future proof way of making it all work.

    P.S. Just noticed that your setup works with one account and doesn't work with another. My guess would be that you either use different executors (Docker doesn't work and Kubernetes works) or different GitLab versions (if the service alias issue has already been fixed).