Caddy Local CA behind Docker

1. Caddy version (caddy version):

Caddy v2

2. How I run Caddy:

Using Caddy Alpine.

a. System environment:

Caddy is run on a pod, inside Kubernetes, inside Minikube.

b. Command:

Our Caddy pod Dockerfile:

ARG CADDY_VERSION=2.1.1
ARG ROUTE53_VERSION=1.0.2

FROM caddy:${CADDY_VERSION}-builder AS builder
ARG ROUTE53_VERSION
RUN caddy-builder \
    github.com/caddy-dns/route53@v${ROUTE53_VERSION}

FROM caddy:${CADDY_VERSION}-alpine
COPY --from=builder /usr/bin/caddy /usr/bin/caddy

COPY root /

c. Service/unit/compose file:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    svc: static
    type: deployment
  name: static
  namespace: "development"
spec:
  replicas: 1
  selector:
    matchLabels:
      svc: static
  strategy:
    rollingUpdate: null
    type: Recreate
  template:
    metadata:
      labels:
        svc: static
    spec:
      containers:
      - image: "local/static:latest"
        name: static
        ports:
        - containerPort: 80
        - containerPort: 443
        volumeMounts:
          - mountPath: "/data/caddy"
            name: static-storage
      restartPolicy: Always
      volumes:
        - name: static-storage
          persistentVolumeClaim:
            claimName: "development-static-volume-claim"

d. My complete Caddyfile or JSON config:

(tls-majority) {
    tls {$ACME_CA_EMAIL} {
        ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
        dns route53
    }

    header Strict-Transport-Security max-age=31536000;
}

(tls-alpha) {
    import tls-majority
}

(tls-beta) {
    import tls-majority
}

(tls-production) {
    import tls-majority
}

(tls-local) {
    tls {$ACME_CA_EMAIL} {
        ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
        ca https://acme-staging-v02.api.letsencrypt.org/directory
        dns route53
    }
}

(default) {
    encode gzip

    log

    import tls-{$TARGET_ENV}

    header {
        Content-Security-Policy "frame-ancestors 'none'"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        X-XSS-Protection "0"
    }
}

https://{$BASE_DOMAIN} {
    import default

    root * /www
    file_server

    @exceptProxy not path /css/* /fonts/* /images/* /js/* /favicon.ico /robots.txt /version.json
    reverse_proxy @exceptProxy http://app:{$APP_SERVICE_PORT_HTTP}
}

# For the Kubernetes liveness probe
:80 {
    respond /_status/ping 200
}

3. What I’d like to do:

We’d like to configure local development environments using Local HTTPS as described here.

My question is relating to:

The first time a root key is used, Caddy will try to install it into the system’s local trust store(s).

Because Caddy runs in Minikube, the local trust store is not that of my computer, but of Minikube instead. It means when I visit the sites in my browser, it won’t recognise the intermediates used to sign the CA.

Is there a way to use Local HTTPS with my setup?

Sure, just install Caddy’s root cert into your system’s trust store. This is the same as with any other self-signed certificates.

The root CA cert will be in /data/pki/authorities/local/root.crt in your container. So make sure to persist that as well (look like you’re only persisting /data/caddy which isn’t enough, you should persist all of /data) and you can add that cert to your various local trust stores.

1 Like

Thanks for your help. I’ll give it a shot :slight_smile:

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.