dockerdocker-in-dockerdocker-api

How to use docker api in dind


I'm using docker in docker. I ran:
docker run --privileged -it docker:dind sh

I already found that I must unset DOCKER_HOST env error-during-connect-get-http-docker-2375-ping to use inner docker.
But how can I use docker api, with non set DOCKER_HOST?

I tried set daemon.json:

{
    "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}

then I get error: "Get “http://docker:2375/_ping”: dial tcp: lookup docker on 10.10.15.22:53: server misbehaving"


Solution

  • Its not clear from your question context if you need to unset DOCKER_HOST. The official docker images manage this variable automatically if it is not set.

    A minimal example of using docker:dind would be this compose file:

    compose.yaml

    volumes:
      certs:
    
    services:
      docker:
        image: docker:dind
        privileged: true
        volumes:
        - certs:/certs
    
      cli:
        image: docker:cli
        depends_on:
        - docker
        volumes:
        - certs:/certs
    

    Check that it works:

    docker compose run cli docker info
    

    Images based off docker:* have an entry-point that automatically manages DOCKER_HOST by checking if /var/run/docker.sock is mounted, or DOCKER_TLS_CERTDIR is unset or not.

    If you are using some other image that you have installed the docker cli into, then you will need to manage dockers configuration yourself. For example add this to the compose.yaml file

      alpine:
        image: alpine
        depends_on:
        - docker
        environment:
          DOCKER_HOST: tcp://docker:2376
          DOCKER_CERT_PATH: /certs/client
          DOCKER_TLS_VERIFY: 1
        volumes:
        - certs:/certs
        command:
        - sh
        - -c
        - |
          apk add docker
          docker info
    

    And verify that the docker cli can connect:

    docker compose run alpine
    

    In the context of GitLab - where the linked error goes, you want a gitlab runner with the following critical config.toml settings. Namely the docker:dind service needs to be run in privileged mode. There is no separate setting for services. "/certs" must be shared between the dind and other docker containers so they can negotiate the tls connection.

      ...
      [runners.docker]
        image = "docker:cli"
        privileged = true
        volumes = ["/certs", "/cache"]
        ...
    

    .gitlab-ci.yml

    build with docker:
      stage: build
      image: docker:cli
      services:
        - name: docker:dind
      script:
        - docker info
    
    build with alpine:
      stage: build
      image: alpine:latest
      services:
      - docker:dind
      variables:
        DOCKER_HOST: tcp://docker:2376
        DOCKER_CERT_PATH: /certs/client
        DOCKER_TLS_VERIFY: 1
      script:
      - apk add docker
      - docker info