Troubleshooting “Client sent HTTP request to HTTPS server” in Docker-in-Docker GitLab CI Setup


2 views

When configuring Docker-in-Docker (DinD) for GitLab CI pipelines, one common pitfall is the TLS communication mismatch between components. The error message "Client sent an HTTP request to an HTTPS server" typically indicates a protocol mismatch between the Docker client and daemon.

The error occurs when:

  • Docker daemon (dind) is configured with TLS enabled (default behavior)
  • Docker client attempts plain HTTP communication
  • Network configurations don't properly expose the required ports

Here's a working configuration that addresses these issues:

# Start the DinD container with proper TLS settings
docker run --privileged --name gitlab-dind -d \
  --network gitlab-runner-net \
  -e DOCKER_TLS_CERTDIR=/certs \
  -e DOCKER_TLS_VERIFY=1 \
  -v docker-certs-ca:/certs/ca \
  -v docker-certs-client:/certs/client \
  docker:19.03.13-dind \
  --tlsverify \
  --tlscacert=/certs/ca/cert.pem \
  --tlscert=/certs/server/cert.pem \
  --tlskey=/certs/server/key.pem
# GitLab Runner configuration with proper TLS
[[runners]]
  name = "gitlab-dind"
  url = "https://gitlab.com"
  token = "YOUR_TOKEN"
  executor = "docker"
  [runners.docker]
    host = "tcp://gitlab-dind:2376"
    tls_verify = true
    image = "docker:19.03.13"
    privileged = true
    volumes = ["/certs/client", "/cache"]

If you want to simplify the setup without TLS (not recommended for production):

# DinD without TLS
docker run --privileged --name gitlab-dind -d \
  --network gitlab-runner-net \
  -e DOCKER_TLS_CERTDIR="" \
  docker:19.03.13-dind \
  --tls=false

# Corresponding runner config
[runners.docker]
  host = "tcp://gitlab-dind:2375"
  tls_verify = false

When troubleshooting:

  • Check container logs: docker logs gitlab-dind
  • Test connection manually: docker -H tcp://gitlab-dind:2376 --tlsverify info
  • Verify certificate paths exist in containers
  • Ensure all components use matching Docker API versions

While disabling TLS might seem tempting for quick fixes, consider:

  • Using certificate authentication for production environments
  • Implementing network segmentation
  • Regularly rotating certificates
  • Monitoring for unauthorized access attempts

Many teams encounter TLS issues when setting up Docker-in-Docker (DIND) with GitLab CI. The "Client sent HTTP request to HTTPS server" error typically occurs when there's a protocol mismatch between the Docker client and daemon configurations.

Here's a working configuration that properly handles TLS:

# Start the DIND service with proper TLS setup
docker run --privileged --name gitlab-dind -d \\
  --network gitlab-runner-net \\
  -e DOCKER_TLS_CERTDIR=/certs \\
  -e DOCKER_TLS_VERIFY=1 \\
  -v docker-certs-ca:/certs/ca \\
  -v docker-certs-client:/certs/client \\
  docker:19.03.13-dind \\
  --storage-driver=overlay2 \\
  --tlsverify \\
  --tlscacert=/certs/ca/cert.pem \\
  --tlscert=/certs/client/cert.pem \\
  --tlskey=/certs/client/key.pem

The runner needs matching TLS settings:

docker run -d --name gitlab-runner \\
  --network gitlab-runner-net \\
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \\
  -v /var/run/docker.sock:/var/run/docker.sock \\
  gitlab/gitlab-runner:alpine

Your runner configuration should include these critical parameters:

[[runners]]
  name = "docker-in-docker"
  url = "https://gitlab.example.com"
  token = "your-runner-token"
  executor = "docker"
  [runners.docker]
    tls_verify = true
    image = "docker:19.03.12"
    privileged = true
    volumes = ["/certs/client", "/cache"]

Here's a working pipeline configuration:

image: docker:19.03.12

services:
  - name: docker:19.03.12-dind
    alias: docker

variables:
  DOCKER_TLS_CERTDIR: "/certs"
  DOCKER_HOST: "tcp://docker:2376"
  DOCKER_TLS_VERIFY: "1"

before_script:
  - docker info

build:
  stage: build
  script:
    - docker build -t my-image .
    - docker run my-image /app/test

If you still encounter issues:

  • Verify certificate permissions inside containers
  • Check network connectivity between containers
  • Ensure consistent Docker versions across components
  • Consider using Docker socket binding as an alternative