Files
devops-base-images-gcp/README.md
T

4.1 KiB

devops-base-images

One-time-setup repo for mirroring minimized base images into Harbor's base-images project, so language builds (via devops-lib's buildDocker.groovy fallback templates) never depend on Docker Hub at build time, and the images that actually ship are the leanest official variant available for each language.

Not wired into any Jenkins pipeline — this is deliberately a manual, occasional operation (re-run when images.txt changes: a new language, a version bump, or picking up an upstream base-image update), using the same one-off kubectl-based DinD pod pattern devops-lib's build-tools.Dockerfile bootstrap already uses, since the VM itself may not have Docker installed directly.

One-time setup

1. Create the Harbor project (public — these are just re-hosted public images, no confidentiality concern, and public avoids needing any pull credentials wired into every build):

Harbor UI → New Project → name base-images → check Public → Create.

Or via API:

curl -X POST -u admin:'<harbor admin password>' -H "Content-Type: application/json" \
  -d '{"project_name":"base-images","metadata":{"public":"true"}}' \
  "http://harbor.192.168.1.7.nip.io/api/v2.0/projects"

2. Run the mirror, via a throwaway DinD pod (same shape as the build-tools image bootstrap):

cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: base-images-mirror
  namespace: jenkins
data:
  images.txt: |
    golang:1.22-alpine golang:1.22-alpine
    alpine:3.20 alpine:3.20
    node:20-alpine node:20-alpine
    python:3.12-alpine python:3.12-alpine
    maven:3-eclipse-temurin-21-alpine maven:3-eclipse-temurin-21-alpine
    eclipse-temurin:21-jre-alpine eclipse-temurin:21-jre-alpine
    php:8.3-cli-alpine php:8.3-cli-alpine
  mirror.sh: |
    #!/bin/sh
    set -eu
    REGISTRY="harbor.192.168.1.7.nip.io"
    PROJECT="base-images"
    while read -r src target; do
        [ -z "$src" ] && continue
        case "$src" in \#*) continue ;; esac
        dest="${REGISTRY}/${PROJECT}/${target}"
        echo "=== ${src} -> ${dest} ==="
        docker pull "$src"
        docker tag "$src" "$dest"
        docker push "$dest"
    done < images.txt
    echo "=== done ==="
---
apiVersion: v1
kind: Pod
metadata:
  name: base-images-mirror
  namespace: jenkins
spec:
  restartPolicy: Never
  containers:
    - name: docker
      image: docker:27-dind
      securityContext:
        privileged: true
      args:
        - "--insecure-registry=harbor.192.168.1.7.nip.io"
      env:
        - name: DOCKER_TLS_CERTDIR
          value: ""
      volumeMounts:
        - name: docker-graph-storage
          mountPath: /var/lib/docker
    - name: docker-cli
      image: docker:27-cli
      command: ["cat"]
      tty: true
      env:
        - name: DOCKER_HOST
          value: tcp://localhost:2375
      volumeMounts:
        - name: mirror
          mountPath: /mirror
        - name: docker-config
          mountPath: /root/.docker
          readOnly: true
  volumes:
    - name: docker-graph-storage
      emptyDir: {}
    - name: mirror
      configMap:
        name: base-images-mirror
        defaultMode: 0755
    - name: docker-config
      secret:
        secretName: harbor-robot-dockerconfig
        items:
          - key: .dockerconfigjson
            path: config.json
EOF

kubectl wait --for=condition=Ready pod/base-images-mirror -n jenkins --timeout=120s
kubectl exec -n jenkins base-images-mirror -c docker-cli -- sh -c '
  for i in $(seq 1 30); do docker info >/dev/null 2>&1 && break; sleep 2; done
  cd /mirror && sh mirror.sh
'
kubectl delete pod base-images-mirror -n jenkins
kubectl delete configmap base-images-mirror -n jenkins

3. Verify:

curl -s http://harbor.192.168.1.7.nip.io/v2/_catalog

Should list base-images/golang, base-images/alpine, base-images/node, base-images/python, base-images/maven, base-images/eclipse-temurin, base-images/php.

Adding a new image / updating a version

Add a line to images.txt, commit, push, then re-run step 2 above (the ConfigMap's images.txt needs updating to match — copy the current file content in, same as the initial setup).