Run Docker-in-Docker behind a corporate proxy on Kubernetes

For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append .md to any kestra.io/docs/* URL for plain Markdown.

Configure Docker-in-Docker (DinD) to work behind a corporate or MITM proxy in a rootless Kubernetes deployment.

In environments that use a proxy intercepting HTTPS traffic, Docker must trust the proxy’s CA certificate when pulling images from remote registries. Without this, image pulls fail with x509: certificate signed by unknown authority.

Prerequisites

  1. Create a ConfigMap for the Docker daemon configuration.

This should include your daemon.json with proxy settings.

Create a file daemon.json:

{
"proxies": {
"http-proxy": "http://mitmproxy.default.svc.cluster.local:8000",
"https-proxy": "http://mitmproxy.default.svc.cluster.local:8000",
"no-proxy": "localhost,127.0.0.1,.svc,.cluster.local,your.nexus.domain.com,kestra-minio"
}
}

Apply the configmap:

kubectl create configmap dind-daemon-config \
--from-file=daemon.json=./daemon.json \
-n kestra
  1. Create a ConfigMap for the MITM Proxy CA certificate.

Assuming you have the CA file saved as mitmproxy-ca.crt, run:

kubectl create configmap dind-ca-certs \
--from-file=ca.crt=./mitmproxy-ca.crt \
-n kestra
  1. Kestra Configuration

Here is a configuration sample you can include in your Helm values.yaml:

configurations:
application:
kestra:
plugins:
configurations:
- type: io.kestra.plugin.scripts.runner.docker.Docker
values:
volume-enabled: true
common:
extraVolumes:
- name: docker-daemon-config
configMap:
name: dind-daemon-config
- name: ca-cert-volume
configMap:
name: dind-ca-certs
extraVolumeMounts:
- name: docker-daemon-config
mountPath: /home/rootless/.config/docker
readOnly: true
- name: ca-cert-volume
mountPath: /home/rootless/.config/docker/certs.d/mitmproxy.default.svc.cluster.local:8000
readOnly: true
- name: ca-cert-volume
mountPath: /home/rootless/mitmproxy
readOnly: true
dind:
enabled: true
base:
rootless:
image:
repository: docker
tag: dind-rootless
pullPolicy: IfNotPresent
securityContext:
runAsUser: 1000
runAsGroup: 1000
args:
- --log-level=fatal
- --group=1000
socketPath: /dind/
tmpPath: /tmp/
resources: {}
extraEnv:
- name: SSL_CERT_FILE
value: /home/rootless/mitmproxy/ca.crt

Here, volume-enabled: true ensures that the CA certificate is mounted from the DinD pod into any container deployed by a Kestra task.

DinD in action

This configuration will help the DinD pod pull the required container images successfully through the MITM proxy.

For Kestra tasks that run in Docker containers (e.g., io.kestra.plugin.scripts.shell.Script), you also need to set the HTTPS_PROXY environment variable and trust the certificate using beforeCommands as shown below. For consistency across tasks, consider configuring these settings as plugin defaults.

id: mitm_proxy
namespace: company.team
tasks:
- id: shell
type: io.kestra.plugin.scripts.shell.Script
containerImage: alpine/curl
beforeCommands:
- apk add --no-cache ca-certificates
- update-ca-certificates
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
volumes:
- /home/rootless/mitmproxy/ca.crt:/usr/local/share/ca-certificates/mitmproxy.crt
env:
HTTPS_PROXY: "mitmproxy.default.svc.cluster.local:8000"
script: |
curl https://httpbin.org/get

How it works

  • daemon.json: tells Docker which proxy settings to use.
  • certs.d: directory where Docker looks for custom CA certificates to trust registries.
  • SSL_CERT_FILE: overrides the TLS stack used by the Docker daemon to trust the MITM CA.
  • HTTP_PROXY, HTTPS_PROXY, NO_PROXY: standard proxy env vars for networking.

Was this page helpful?