Search code examples
dockergitlabgitlab-cigitlab-ci-runner

How to access GitLab instance container inside the GitLab Runner container to clone the repository on the same machine?


I am fully aware that setting up GitLab and GitLab Runner on the same machine is a bad practice, but I have done it solely for testing purposes. I installed GitLab and GitLab Runner via docker on Ubuntu OS.

The pipeline gives the following error:

enter image description here

As you see, the runner can't clone from the repository. What I have done so far is:

This is the docker-compose file

version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    hostname: 'localhost:180'
    container_name: 'gitlab'
    restart: unless-stopped
    networks:
      - gitlab-network    
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://localhost:180'        
    ports:
      - '180:80'
      - '1443:443'
      - '122:22'
      - '1587:587'
    volumes:
      - 'gitlab_config:/etc/gitlab'
      - 'gitlab_logs:/var/log/gitlab'
      - 'gitlab_data:/var/opt/gitlab'
    shm_size: '6gb'
  gitlab-runner:
    container_name: 'gitlab-runner'
    image: 'gitlab/gitlab-runner:latest'
    networks:
      - gitlab-network      
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./config:/etc/gitlab-runner
    restart: unless-stopped
volumes:
  gitlab_config : {}
  gitlab_logs : {}
  gitlab_data: {}
networks:
  gitlab-network:
    driver: bridge

This is the /etc/gitlab-runner/config.toml

concurrent = 1
check_interval = 0
shutdown_timeout = 0

[session_server]
  session_timeout = 1800


[[runners]]
  name = "my-runner"
  url = "http://gitlab/"
  id = 3
  token = "glrt-rg-noV98QitS65raRQzk"
  token_obtained_at = 2023-12-05T10:33:20Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.docker]
    tls_verify = false
    image = "alpine:latest"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0
    network_mtu = 0

My understanding

The meaning of localhost inside the GitLab Runner container is different and it points to the container itself, not the host machine. So I tried to set the extra_host in different ways as follows:

  • extra_hosts = ["localhost:gitlab"] : It reports error that the gitlab is not a valid url
  • extra_hosts = ["localhost:IP_ADDRESS_HOST_MACHINE"]: didn't work
  • extra_hosts = ["localhost:IP_ADDRESS_GITLAB_CONTAINER"]: didn't work

I also set network_mode: "host" in both services, but didn't work.

I have been grappling with this issue for about a week now, and I have tried various methods, but I haven't reached any conclusion.


Solution

  • While @sytech was right about adding the clone_url to [[runners]] (for some reason I had it under [[runners]][runners.docker]), we also need to have network_mode under [[runners]][runners.docker] (src).

    network_mode can be a single Docker network name. If you are like me and define a name for your networks, just use the name you have defined. For example in a Docker Compose file I have:

    ...
    networks:
      gitlab-network:
        enable_ipv6: false
        name: gitlab-network
    ...
    

    therefore I use gitlab-network as the value of network_mode in the runner’s config.toml:

    ...
    [[runners]]
      clone_url = 'http://gitlab'
      ...
      [runners.docker]
        network_mode = 'gitlab-network'
        ...
    

    If you don’t define a Docker network’s name, it will be generated (as @mbauter puts it) from the name of the service plus the name given inside the [Docker Compose file]. I presume that the name given inside the [Docker Compose file] is the value of the top-level name in that file OR the project name you specify on the command-line (e.g. docker compose -f compose.yml -p some_cool_project_name ...).

    Anyway, you can check the actual network name in docker inspect "$container_name", e.g. using the following command (src):

    docker container inspect \
      -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' \
      "$container_name"