This example demonstrates how to build a Docker image within a Tekton Task using a Docker-in-Docker (DinD) sidecar.
Example
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
generateName: dind-sidecar-
spec:
taskSpec:
steps:
- image: mirror.gcr.io/library/docker@sha256:0752ca4e936da012c173c119217c0f9599b3b191c1557e53206d5d06d2627580
name: client
env:
# Connect to the sidecar over TCP, with TLS.
- name: DOCKER_HOST
value: tcp://localhost:2376
# Verify TLS.
- name: DOCKER_TLS_VERIFY
value: '1'
# Use the certs generated by the sidecar daemon.
- name: DOCKER_CERT_PATH
value: /certs/client
workingDir: /workspace
script: |
#!/usr/bin/env sh
set -e
# Run a Docker container.
docker run busybox echo hello
# Write a Dockerfile and `docker build` it.
cat > Dockerfile << EOF
FROM ubuntu
RUN apt-get update
ENTRYPOINT ["echo", "hello"]
EOF
docker build -t hello .
docker images
# ...then run it!
docker run hello
volumeMounts:
- mountPath: /certs/client
name: dind-certs
sidecars:
- image: mirror.gcr.io/library/docker@sha256:0752ca4e936da012c173c119217c0f9599b3b191c1557e53206d5d06d2627580
name: server
args:
- --storage-driver=vfs
- --userland-proxy=false
- --debug
computeResources:
requests:
memory: "512Mi"
securityContext:
privileged: true
env:
# Write generated certs to the path shared with the client.
- name: DOCKER_TLS_CERTDIR
value: /certs
volumeMounts:
- mountPath: /certs/client
name: dind-certs
# Wait for the dind daemon to generate the certs it will share with the
# client. StartupProbe handles slow Docker daemon initialization.
startupProbe:
periodSeconds: 1
failureThreshold: 30 # Allow up to 30 seconds for Docker daemon to start
exec:
command: ['ls', '/certs/client/ca.pem']
# ReadinessProbe verifies Docker daemon is actually ready to accept commands.
# Note: With k8s native sidecar support, startupProbe is honored but
# readinessProbe may not be.
readinessProbe:
periodSeconds: 2
exec:
command: ['docker', 'info']
volumes:
- name: dind-certs
emptyDir: {}
How It Works
Sidecar Starts Docker Daemon
The sidecar container runs a Docker daemon with TLS enabled. It generates certificates and writes them to a shared volume at /certs/client.
Startup Probes Wait for Daemon
The startupProbe waits for the certificates to be generated (up to 30 seconds). The readinessProbe verifies the daemon is ready to accept commands.
Client Connects to Daemon
The client step configures the Docker CLI to connect to the sidecar daemon using environment variables:
DOCKER_HOST=tcp://localhost:2376 - Connect via TCP
DOCKER_TLS_VERIFY=1 - Enable TLS verification
DOCKER_CERT_PATH=/certs/client - Use shared certificates
Build and Run Docker Image
The client step:
- Runs a simple busybox container to verify connectivity
- Creates a Dockerfile
- Builds an image tagged as
hello
- Runs the newly built image
Security Considerations
The Docker daemon sidecar requires privileged: true to function. This grants significant permissions to the container. Only use this in trusted environments.
Docker Daemon Configuration
The daemon is configured with specific arguments:
--storage-driver=vfs - Uses VFS storage driver (slower but more compatible)
--userland-proxy=false - Disables userland proxy
--debug - Enables debug logging
TLS Certificate Sharing
The pattern for sharing TLS certificates:
- Sidecar sets
DOCKER_TLS_CERTDIR=/certs to generate certs
- Both containers mount the same
dind-certs volume
- Client reads certificates from
/certs/client
- Docker CLI automatically uses these certificates
Expected Output
hello
Sending build context to Docker daemon...
Step 1/3 : FROM ubuntu
Step 2/3 : RUN apt-get update
Step 3/3 : ENTRYPOINT ["echo", "hello"]
Successfully built...
Successfully tagged hello:latest
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest abc123def456 1 second ago 77.8MB
hello
Alternative Approaches
For production use, consider:
- Kaniko: Builds images without requiring privileged mode
- Buildah: Daemonless container builds
- BuildKit: Modern Docker build backend with better caching
These alternatives are more secure and work better in restricted environments.
Key Concepts
- Sidecars: Containers that run alongside task steps to provide services
- Docker-in-Docker (DinD): Running Docker daemon inside a container
- Startup Probes: Wait for slow-starting containers to be ready
- Shared Volumes: Pass data between steps and sidecars
- TLS Security: Secure communication between Docker client and daemon
- Privileged Containers: Required for DinD but should be used carefully
Next Steps