<p>I work on a Kubernetes cluster based CI-CD pipeline.
The pipeline runs like this:</p>

<ul>
<li>An ECR machine has Docker.</li>
<li>Jenkins runs as a container.</li>
<li>"Builder image" with Java, Maven etc is built.</li>
<li>Then this builder image is run to build an app image(s)</li>
<li>Then the app is run in kubernetes AWS cluster (using Helm).</li>
<li>Then the builder image is run with params to run Maven-driven tests against the app.</li>
</ul>

<p>Now part of these steps doesn't require the image to be pushed. E.g. the builder image can be cached or disposed at will - it would be rebuilt if needed.</p>

<p>So these images are named like <code>mycompany/mvn-builder:latest</code>.</p>

<p>This works fine when used directly through Docker.</p>

<p>When Kubernetes and Helm comes, it wants the images URI's, and try to fetch them from the remote repo. So using the "local" name <code>mycompany/mvn-builder:latest</code> doesn't work:</p>

<pre><code>Error response from daemon: pull access denied for collab/collab-services-api-mvn-builder, repository does not exist or may require 'docker login'
</code></pre>

<p>Technically, I can name it <code>&lt;AWS-repo-ID&gt;/mvn-builder</code> and push it, but that breaks the possibility to run all this locally in <code>minikube</code>, because that's quite hard to keep authenticated against the silly AWS 12-hour token (remember it all runs in a cluster).</p>

<p>Is it possible to mix the remote repo and local cache? In other words, can I have Docker look at the remote repository and if it's not found or fails (see above), it would take the cached image?</p>

<p>So that if I use <code>foo/bar:latest</code> in a Kubernetes resource, it will try to fetch, find out that it can't, and would take the local <code>foo/bar:latest</code>?</p>

Ondra Žižka
<p>I <em>believe</em> an <code>initContainer</code> would do that, provided it had access to <code>/var/run/docker.sock</code> (and your cluster allows such a thing) by conditionally pulling (or <code>docker load</code>-ing) the image, such that when the "main" <code>container</code> starts, the image will always be cached.</p>

<p>Approximately like this:</p>

<pre><code>spec:
  initContainers:
  - name: prime-the-cache
    image: docker:18-dind
    command:
    - sh
    - -c
    - |
      if something_awesome; then
          docker pull from/a/registry
      else
          docker load -i some/other/path
      fi
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run/docker.lock
      readOnly: true
  containers:
  - name: primary
    image: a-local-image
volumes:
- name: docker-sock
  hostPath:
     path: /var/run/docker.sock
</code></pre>
