Waiting for DIND in style in Drone CI

I've been using Drone CI lately for some projects (together with Gitea). It's been pretty awesome so far and setting up a git hosting server and CI taught me more than one thing.

Running DIND is often something required on CI these days, and Drone CI offers some short explanation of how to do it: Run docker:dind as a service, passing the docker service socket using a volume to the actual step's image:

---
kind: pipeline
name: default
steps:
- name: test
image: docker:dind
volumes:
- name: dockersock
path: /var/run
commands:
- sleep 5 # give docker enough time to start
- docker ps -a
services:
- name: docker
image: docker:dind
privileged: true
volumes:
- name: dockersock
path: /var/run
volumes:
- name: dockersock
temp: {}

It uses a pragmatic sleep 5 to give the docker service some time to get up and running (I've also seen examples with sleep 10). This probably works in 99% of pipelines, but docker may need longer than you're waiting or actually you may be wasting time waiting while docker already is idling. You never know…

Instead I'd like to share my little script which checks if docker is running, waiting between tries for a second, and times out if too many unsuccessful tries are happening. I keep the following code in a ci/wait-for-docker.sh file, which get's called instead of sleeping for a fixed time:

#!/bin/sh
MAX_TRIES=${1-10}
SLEEP=${2-1}
TRIES=1
until docker ps -q &> /dev/null; do
if [ $TRIES -ge $MAX_TRIES ]; then
echo "Darn! Timeout waiting for docker."
exit 1
fi
echo "Waiting for docker…"
TRIES=$(($TRIES+1))
sleep $SLEEP
done
echo "Yay! Docker is ready!"

It defaults to max 10 tries with sleeping 1 second in between tries, but you can override those values by passing arguments.