From b13a8cec785639b72a6975e1f95883713be0b56f Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sat, 15 Aug 2026 15:22:11 +1000 Subject: [PATCH] Add CA-baked plugin-docker-buildx image + buildah CI Bake the internal Vault-PKI CA into a rebuild of woodpeckerci/plugin-docker-buildx so k8s buildx jobs can push to artifactapi's docker-internal registry over TLS. - Dockerfile: copy unkin-ca.crt into /etc/docker/certs.d//ca.crt and the system trust store - unkin-ca.crt: vault-ca-cert bundle (root + intermediate) - .woodpecker/build.yaml: PR gate, buildah build-only - .woodpecker/release.yaml: on v* tag, buildah build + credless push to docker-internal with --tls-verify=false (bootstrap) --- .woodpecker/build.yaml | 20 +++++++++++++++++++ .woodpecker/release.yaml | 32 ++++++++++++++++++++++++++++++ Dockerfile | 6 ++++++ README.md | 29 ++++++++++++++++++++++++++- unkin-ca.crt | 42 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 .woodpecker/build.yaml create mode 100644 .woodpecker/release.yaml create mode 100644 Dockerfile create mode 100644 unkin-ca.crt diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml new file mode 100644 index 0000000..2ffb30e --- /dev/null +++ b/.woodpecker/build.yaml @@ -0,0 +1,20 @@ +when: + - event: pull_request + +steps: + # PR gate: build the CA-baked plugin image only, no push. buildah runs + # unprivileged in-cluster, so use the vfs storage driver + chroot isolation. + - name: build + image: quay.io/buildah/stable + commands: + - buildah build --isolation chroot --storage-driver vfs -t plugin-docker-buildx:${CI_COMMIT_SHA} . + backend_options: + kubernetes: + serviceAccountName: plugin-docker-buildx + resources: + requests: + memory: 512Mi + cpu: 1 + limits: + memory: 2Gi + cpu: 2 diff --git a/.woodpecker/release.yaml b/.woodpecker/release.yaml new file mode 100644 index 0000000..0c60e71 --- /dev/null +++ b/.woodpecker/release.yaml @@ -0,0 +1,32 @@ +when: + - event: tag + ref: refs/tags/v* + +steps: + # Build the CA-baked plugin image and push it to artifactapi's docker-internal + # registry. buildah runs unprivileged in-cluster (vfs + chroot isolation). + # + # Push is credential-less: the in-cluster runner already has push access to the + # artifactapi docker-internal registry (same pattern as autobackup-operator / + # jellyfin-ha). --tls-verify=false is a deliberate bootstrap: THIS image is what + # teaches k8s buildx to trust artifactapi's internal CA, so its own push cannot + # yet rely on that trust. + - name: release + image: quay.io/buildah/stable + environment: + IMG: artifactapi.k8s.syd1.au.unkin.net/docker-internal/plugin-docker-buildx + commands: + - buildah build --isolation chroot --storage-driver vfs -t $${IMG}:${CI_COMMIT_TAG} . + - buildah tag --storage-driver vfs $${IMG}:${CI_COMMIT_TAG} $${IMG}:latest + - buildah push --storage-driver vfs --tls-verify=false $${IMG}:${CI_COMMIT_TAG} + - buildah push --storage-driver vfs --tls-verify=false $${IMG}:latest + backend_options: + kubernetes: + serviceAccountName: plugin-docker-buildx + resources: + requests: + memory: 512Mi + cpu: 1 + limits: + memory: 2Gi + cpu: 2 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5e0c85d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM woodpeckerci/plugin-docker-buildx:latest +# buildkit reads this to trust artifactapi's internal-CA registry on push +COPY unkin-ca.crt /etc/docker/certs.d/artifactapi.k8s.syd1.au.unkin.net/ca.crt +# fallback: system trust store (docker login / other code paths) +COPY unkin-ca.crt /usr/local/share/ca-certificates/unkin-ca.crt +RUN cat /usr/local/share/ca-certificates/unkin-ca.crt >> /etc/ssl/certs/ca-certificates.crt || true diff --git a/README.md b/README.md index a1b6372..5d29b46 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,30 @@ # plugin-docker-buildx -Woodpecker plugin-docker-buildx image with the internal Vault-PKI CA baked in (trusts artifactapi) \ No newline at end of file +A drop-in rebuild of `woodpeckerci/plugin-docker-buildx` with the internal +Vault-PKI CA baked in. + +## Why + +The stock `woodpeckerci/plugin-docker-buildx` image does not trust artifactapi's +internal CA, so k8s Woodpecker buildx jobs cannot push to +`artifactapi.k8s.syd1.au.unkin.net/docker-internal/*` — buildkit needs +`/etc/docker/certs.d//ca.crt` inside the plugin container, and the k8s +backend has no way to inject it. + +This image copies the `vault-ca-cert` bundle (root + intermediate) into that path +plus the system trust store, so pipelines can `settings.registry: +artifactapi.k8s.syd1.au.unkin.net` and push over TLS. + +## Published as + +`artifactapi.k8s.syd1.au.unkin.net/docker-internal/plugin-docker-buildx:` (and `:latest`) + +## Bootstrap + +This image is itself built and pushed by **buildah** (`.woodpecker/release.yaml`), +not by buildx, using `buildah push --tls-verify=false`. buildah is used precisely +because it sidesteps the buildx CA-trust problem that this image exists to fix — +its own push therefore cannot rely on that trust yet. + +Once published, point Woodpecker docker-buildx steps at this image instead of the +upstream one to push to the docker-internal registry. diff --git a/unkin-ca.crt b/unkin-ca.crt new file mode 100644 index 0000000..58d7a5a --- /dev/null +++ b/unkin-ca.crt @@ -0,0 +1,42 @@ +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIULZAR/QcvAnxdi04S6bXhNeazozYwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAxMJdW5raW4ubmV0MB4XDTI0MDQyNzExMzcyMloXDTI5MDQy +NjExMzc1MlowKzEpMCcGA1UEAxMgdW5raW4ubmV0IEludGVybWVkaWF0ZSBBdXRo +b3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDq0ZU2DnuYW5s +E3lPjVe2Ns6cPu64yx1GLVqB5VbOUs71ThRjPjvEwE98YtGMza8ok0CQSqS2qX8z +vnMbnVCaWKjCnem/dtQtB+8WCu5uQuNHhwqxgw1tD/klAkVLWGgTPDEgasvjDMkc +sW8in/BhtrV9YA/lQGpge+j9/MFXhlnvaLCPybFifPRX9Yc5CcnhSzLSzFPO4PJx +VH4Qu9eByyKHMTvgcCy6p9qjjzz+8dtAlxeIsgfTEdvtfCPowsF+v2XooutTsJt0 +xUDvUDu4xV6tVCEOYRA2cZHkLRBhV289M0hocHrsGqMmA1+j0skwwt/6UkVHqlCT +mitItX+RAgMBAAGjgewwgekwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFEp/+grAdVqRSeb9xJjSeZYNW32MMB8GA1UdIwQYMBaAFBqc +v6Y+hfHt4EjgKa/uoQGEHTknMEcGCCsGAQUFBwEBBDswOTA3BggrBgEFBQcwAoYr +aHR0cHM6Ly92YXVsdC5zZXJ2dWNlLmNvbnN1bC92MS9wa2lfcm9vdC9jYTA9BgNV +HR8ENjA0MDKgMKAuhixodHRwczovL3ZhdWx0LnNlcnZpY2UuY29uc3VsL3YxL3Br +aV9yb290L2NybDANBgkqhkiG9w0BAQsFAAOCAQEAM0FS8tscZe7yly/gM7jO6lx5 +muMFusifjUIrcQGnZBkoECeuUVPNTs3e/Th+XaxjCnmSpqSNT3z9Irr6Hhxf7n03 +4+hpF3G0bf1yh4DRex/0ua3szvgo91RwyKVQM1BHIA1PwdF8csO+LT4FTMILzo4U +DdSVvDEIaxYYQCDNfAD81n+8lmFbabupfsKbkSTR+sNTS+TMnLpN8YwSXdB0e+RU +eEZRNVu0jKmbE8U/66Sc33YLe6cxbCclHA+G4giGwEP+lYZk+rFjmr6ci9bj5yyN +Sznr7xdW0ofOdACAQFFy5KTZqCDjIrvk12vUn4bSsXmWVIQEd+jPx6wuxD/rSw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDLzCCAhegAwIBAgIUIDADwsHIrQ8dfncpechBdIUCQdIwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAxMJdW5raW4ubmV0MB4XDTI0MDQyNzExMjcwMloXDTM0MDQy +NTExMjczMlowFDESMBAGA1UEAxMJdW5raW4ubmV0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA3ENPv7R7gCUJAg8Q4hB2LEZSdvbK155YbcrguLDDnu6m +2fkJn8jYMMW3Z6/+Y04ouGwi6sKup8ggTb217sY+dC4IUZjotDPAhruxfXVQAh0v +Yr3RYoxVDrm4nRSFLo1RA4Qt+1KK299mHGQf9iAiwbsFp5mDrJT9uz15FE2uWmbK +8/onMyJC4fnkMihVN6NIgTtjpHYNm5aAJwxoWldTopgF0ucb7X3XVPNbKAmd3Avd +lsOo6m751zSZ0HvJOxgRSy7lvPzMuUfCQsOcmI4O4+Z2FL4Y7p+T9DvWkciC7L3i +tBiK30fPfGKNpWaof1ONCcPQNjMwWcEFXqSiWUOXkwIDAQABo3kwdzAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGpy/pj6F8e3gSOAp +r+6hAYQdOScwHwYDVR0jBBgwFoAUGpy/pj6F8e3gSOApr+6hAYQdOScwFAYDVR0R +BA0wC4IJdW5raW4ubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQA5xocILzuvD+R2Iub1 +UnTdcVpgNcxJmESz0eX4UrkcBmddtuFINXvDTv5//XTFs78LsVVSf00xZ+2C62Xe +xRdCdluHN8VDCAKulP4XJY1BiZ7im0v+iMgPDKhq4OXb86WFYI/8J6uRm7oIAwj1 +zhhKxMimkzli+yHB8ipL15W7l68CMUgmOjFA+EG6sbfadFpQTX/h6TVj3FQPkU/p +UJEm2XjlGNAKGJrNRU47PM4vRDv5Joyowp9zv/pHFXvUJladaJupMKRJQVWQz1US +EXE67rawG79s3vm8dDolnbli/IhPHtjDRIprxAwrMs5tt9cY0xsRkFBZVcAOjrpb +4gqd +-----END CERTIFICATE-----