This article was originally published on DevOpsStart.com. Here's a quick fix for the dreaded 'Cannot connect to the Docker daemon' error in GitLab CI.
The Problem
You have a GitLab CI job that tries to run docker build or docker info, and it fails with this error:
Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
The error means your job is running inside a container that has the docker CLI installed but no Docker daemon (dockerd) service to talk to. The default docker image from Docker Hub ships only the client. Without a running daemon, every docker command returns this error.
Root Causes
Three things cause this error.
1. Missing docker service in .gitlab-ci.yml
You must define a services block that runs the daemon. The standard approach is:
services:
- docker:dind
Without this, your job has no daemon to connect to.
2. Incorrect or missing DOCKER_HOST variable
When you use the docker executor (the default GitLab Runner executor), the daemon runs as a separate container in the same Pod. You must tell the client where to find it:
variables:
DOCKER_HOST: tcp://docker:2375
If DOCKER_HOST is set to tcp://localhost:2375 or missing entirely, the client looks for a local Unix socket that does not exist inside your job container. The job container has no socket file.
3. Runner not in privileged mode
The docker:dind service requires privileged mode to run its own Docker daemon. If your GitLab Runner's config.toml has privileged = false or is unset, the dind container cannot start. Check your runner configuration:
$ cat /etc/gitlab-runner/config.toml
[[runners]]
name = "my-runner"
url = "https://gitlab.com/"
token = "..."
executor = "docker"
[runners.docker]
privileged = true
pull_policy = "always"
If privileged is false or absent, the dind service never boots, and you get the Cannot connect to the Docker daemon error.
The Solution
A complete fix takes three steps.
Step 1: add the docker:dind service
Add this to your .gitlab-ci.yml:
image: docker:24.0.7
services:
- name: docker:dind
alias: docker
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
The DOCKER_HOST value tcp://docker:2375 tells the client to use the service container named docker (the GitLab Runner resolves the service alias to the container hostname). The DOCKER_TLS_CERTDIR: "" disables TLS for simplicity.
Step 2: test with a simple job
Add a minimal job to verify the fix works:
build:
stage: build
script:
- docker info
- docker build -t my-app .
The docker info command confirms the daemon is reachable. If it succeeds, your pipeline is ready.
Step 3: check runner logs
If docker info still fails, inspect the runner logs. On your GitLab Runner host, run:
$ docker logs <runner-container-id> --tail 50
Look for lines like:
Starting container service-docker:dind-0 ...
If you see no such line, the service never started. Check privileged mode again in config.toml.
Prevention
To avoid this error in future:
- Always add
services: - docker:dindto any job that needsdockercommands. - Always set
DOCKER_HOST: tcp://docker:2375as a top-level variable in your pipeline. - Verify your GitLab Runner's
config.tomlhasprivileged = truebefore you push new jobs. - For a production-grade setup, consider using the
docker:24.0.7-dindimage variant. It bundles the daemon and the client in one image, reducing the chance of version mismatches.
Top comments (0)