Connor Butch
Connor Butch

Reputation: 688

Find url/ip of container running in docker-compose in gitlab ci

I have an application that runs in docker-compose (for acceptance testing). The acceptance tests work locally, but they require the host (or ip) of the webservice container running in docker-compose in order to send requests to it. This works fine locally, but I cannot find the ip of the container when it is running in a gitlab ci server. I've tried the following few solutions (all of which work when running locally, but none of which work in gitlab ci) to find the url of the container running in docker-compose in gitlab ci server:

  1. use "docker" as the host. This works for an application running in docker, but not docker-compose
  2. use docker-inspect to find the ip of the container (docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' reading-comprehension)
  3. assign a static ip to the container using a network in docker-compose.yml (latest attempt).

The gitlab ci file can be found here: https://gitlab.com/connorbutch/reading-comprehension/-/blob/9-list-all-assessments/.gitlab-ci.yml

    image: connorbutch/gradle-and-java-11:alpha

variables:
  GRADLE_OPTS: "-Dorg.gradle.daemon=false"
  DOCKER_HOST: "tcp://docker:2375"
  DOCKER_DRIVER: "overlay2"

before_script:
  - export GRADLE_USER_HOME=`pwd`/.gradle

services:
  - docker:stable-dind

stages:
  - build
  - docker_build
  - acceptance_test

unit_test:
  stage: build
  script: ./gradlew check
  cache:
    key: "$CI_COMMIT_REF_NAME"
    policy: pull
    paths:
      - build
      - .gradle

build:
  stage: build
  script:
    - ./gradlew clean quarkusBuild
    - ./gradlew clean build -Dquarkus.package.type=native -Dquarkus.native.container-build=true
  cache:
    key: "$CI_COMMIT_REF_NAME"
    policy: push
    paths:
      - build
      - .gradle
  artifacts:
    paths:
      - reading-comprehension-server-quarkus-impl/build/

docker_build:
  stage: docker_build
  script:
    - cd reading-comprehension-server-quarkus-impl
    - docker build -f infrastructure/Dockerfile -t registry.gitlab.com/connorbutch/reading-comprehension:$CI_COMMIT_SHORT_SHA  .
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker push registry.gitlab.com/connorbutch/reading-comprehension:$CI_COMMIT_SHORT_SHA

acceptance_test:
  stage: acceptance_test
  only:
    - merge_requests
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - cd reading-comprehension-server-quarkus-impl/infrastructure
    - export IMAGE_TAG=$CI_COMMIT_SHORT_SHA
    - docker-compose up -d & ../../wait-for-it-2.sh
    - cd ../..
    - ./gradlew -DBASE_URL='192.168.0.8' acceptanceTest
  artifacts:
    paths:
      - reading-comprehension/reading-comprehension-server-quarkus-impl/build/

The docker-compose file can be found here: https://gitlab.com/connorbutch/reading-comprehension/-/blob/9-list-all-assessments/reading-comprehension-server-quarkus-impl/infrastructure/docker-compose.yml

Find the output of one of the failed jobs here: https://gitlab.com/connorbutch/reading-comprehension/-/jobs/734771859

#This file is NOT ever intended for use in production.  Docker-compose is a great tool for running
#database with our application for acceptance testing.
version: '3.3'

networks:
  network:
    ipam:
      driver: default
      config:
        - subnet: 192.168.0.0/24

services:
  db:
    image: mysql:5.7.10
    container_name: "db"
    restart: always
    environment:
       MYSQL_DATABASE: "rc"
       MYSQL_USER: "user"
       MYSQL_PASSWORD: "password"
       MYSQL_ROOT_PASSWORD: "password"
       MYSQL_ROOT_HOST: "%"
    networks:
      network:
        ipv4_address: 192.168.0.4
    ports:
      - '3306:3306'
    expose:
      - '3306'
    volumes:
      - db:/var/lib/mysql
  reading-comprehension-ws:
    image: "registry.gitlab.com/connorbutch/reading-comprehension:${IMAGE_TAG}"
    container_name: "reading-comprehension"
    restart: on-failure
    environment:
      WAIT_HOSTS: "db:3306"
      DB_USER: "user"
      DB_PASSWORD: "password"
      DB_JDBC_URL: "jdbc:mysql://192.168.0.4:3306/rc"
    networks:
      network:
        ipv4_address: 192.168.0.8
    ports:
      - 8080:8080
    expose:
      - 8080
volumes:
  db:

Does anyone have any idea on how to access the ip of the container running in docker-compose on gitlab ci server? Any suggestions are welcome.

Thanks,

Connor

Upvotes: 5

Views: 4911

Answers (1)

Facty
Facty

Reputation: 547

This is little bit tricky, just few days ago I had similar problem but with VPN from CI to client :)

EDIT: Solution for on-premise gitlab instances

Create custom network for gitlab runners:

docker network create --subnet=172.16.0.0/28 \
 --opt com.docker.network.bridge.name=gitlab-runners \
 --opt com.docker.network.bridge.enable_icc=true \
 --opt com.docker.network.bridge.enable_ip_masquerade=true \
 --opt com.docker.network.bridge.host_binding_ipv4=0.0.0.0 \
 --opt com.docker.network.driver.mtu=9001 gitlab-runners

Attach new network to gitlab-runners

# /etc/gitlab-runner/config.toml
[[runners]]
....
   [runners.docker]
   ....
   network_mode = "gitlab-runners"

Restart runners.

And finally gitlab-ci.yml

start-vpn:
    stage: prepare-deploy
    image: docker:stable
    cache: {}
    variables:
        GIT_STRATEGY: none
    script:
        - >
            docker run -it -d --rm
            --name vpn-branch-$CI_COMMIT_REF_NAME
            --privileged
            --net gitlab-runners
            -e VPNADDR=$VPN_SERVER
            -e VPNUSER=$VPN_USER
            -e VPNPASS=$VPN_PASSWORD
            auchandirect/forticlient || true && sleep 2
        - > 
            docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 
            vpn-branch-$CI_COMMIT_REF_NAME > vpn_container_ip
    artifacts:
        paths:
        - vpn_container_ip

And in next step you can use something like:

before_script:
        - ip route add 10.230.163.0/24 via $(cat vpn_container_ip) # prod/dev
        - ip route add 10.230.164.0/24 via $(cat vpn_container_ip) # test

EDIT: Solution for gitlab.com

Base on gitlab issue answer port mapping in DinD is bit different from nonDinD gitlab-runner and for exposed ports you should use hostname 'docker'.

Example:

services:
  - docker:stable-dind

variables:
  DOCKER_HOST: "tcp://docker:2375"

stages:
  - test

test env:
  image: tmaier/docker-compose:latest
  stage: test
  script:
    # containous/whoami with exposed port 80:80
    - docker-compose up -d
    - apk --no-cache add curl
    - curl docker:80              # <------- 
    - docker-compose down

Upvotes: 6

Related Questions