> For the complete CircleCI developer hub index, see [llms.txt](https://circleci.com/developer/llms.txt)

# cci-x/docker-registry-image-cache

Save and restore a docker image cache using a registry.

This orb provides commands which may be used as an alternative to the CircleCI 'docker_layer_caching' feature. It is intended to be used with 'machine' executors or jobs which use 'setup_remote_docker'.

Using this orb

This orb requires a docker registry which will be used to push and pull images. Popular docker registries include Docker Hub, Google Container Registry, AWS Elastic Container Registry, and Quay.io. If you already use one of these registries in your job you are all set. The registry you choose for the cache may be different from the registry you use to publish images.

Using pulled images as a cache for docker build

To use images pulled from a docker registry as a cache for image building you must use `--cache-from` with a list of docker images. This orb provides a `build` command to automatically add the images listed in the 'images' field to 'docker build'. If you use a script or a tool like docker-compose to build images you will need to pass the list of images yourself. With docker-compose make sure to set `build.cache_from` in your docker-compose.yml.

Image tags

The images listed in 'with-save-restore-images.images' are effectively the keys used for the cache. For best results you may want to use two tags, one which is gauranteed to exist (for example a tag that is pushed when CI runs on the 'master' branch) and one which is more likely to match the current Dockerfile (for example a tag which includes the current branch name or a hash of the Dockerfile).

If you are building multiple docker images, you can include one or more tags for each image.


## Commands

### with-save-restore-images

Restore a cache, run steps, then save a cache of the new image.

The docker pull and docker push are optional, any failures will be ignored so that missing images do not cause the job to fail.


| Parameter | Type | Default | Description |
|---|---|---|---|
| `images` | string |  | A list of docker image names, separated by spaces, to pull from a registry
and push to the registry when the nested steps finish. If repository is set the
images will be prefixed with the value of that field before pulling and pushing.
 |
| `repository` | string |  | A prefix added to each image name before pulling and pushing from the registry.
A repository may be just the hostname of the registry, or it may include the organization
prefix as well.
 |
| `steps` | steps |  | Steps to run after the cache has been pulled from a registry, and before pushing the
new images to the registry.
Any steps which build docker images must be included in this list.
 |
| `save-when` | string | on_success | Condition used as the when attribute of the save cache operation.
See https://circleci.com/docs/2.0/configuration-reference/#the-when-attribute
for supported values.
 |
| `image-filename` | string | /tmp/docker-cache/images | Path to a file used to store the list of images.
You most likely don't need to change this.
 |
| `parallelism` | integer | 1 | Maximum number of processess to use when pushing and pulling images.
 |

### build

Build a cache image adding a --cache-from parameter for every image in the list
provided to with-save-restore-images.


| Parameter | Type | Default | Description |
|---|---|---|---|
| `command` | string |  | A `docker build` command to run. Should include a `--tag` parameter for
the image.
 |
| `step-name` | string | docker build | Name for the step.
 |
| `image-filename` | string | /tmp/docker-cache/images | Path to a file used to store the list of images. Must match the path provided to
'with-save-restore-images'.
You most likely don't need to change this.
 |

### tag

Tag a group of Docker images. To make the cache work when you are not using the orb's `build` command,
your build must produce Docker images with the tags listed in the `images` parameter. If you do not wish
to change your existing tagging, or you are using docker-compose or scripts where the image tags
cannot easily be controlled, then this command will help.


| Parameter | Type | Default | Description |
|---|---|---|---|
| `tags` | string |  | A list of image tag pairs, separated by spaces, which will be passed to docker tag.
The first item in the pair is the source tag, and the second the destination.
 |
| `step-name` | string | Tag docker images | Name for the step.
 |

## Examples

### cache_using_branch_name_key

This example demonstrates how to use this orb to speed up a 'docker build'. It uses the git branch name as a cache key, and the master branch as a fallback when the branch is new.

The first step is to log into a GCR registry. The values for these REGISTRY_ variables may be set by project environment variables or from a CircleCI Context.

Once login is complete the 'with-save-restore-images' command pulls images from a registry. This example uses two images. An image tagged with 'master' which acts as a base for new branches, and an image tagged with the name of the git branch. This example removes any slashes from the git branch name using bash string substitution ('${var/\//-}'). The images are listed using the YAML '>-' symbol, which replaces newlines with spaces and removes trailing newlines. This allows you to list images one per line.

The nested step uses the 'build' command to build a new docker image. The orb command takes care of adding the '--cache-from' arguments to 'docker build' so that the images that were pulled are used as a cache. You may use as many nested steps as necessary. Only steps which build docker images need to be nested under 'with-save-restore-images'.

Once all the nested steps have completed the 'with-save-restore-images' command pushes all the 'images' to the same registry where it pulled from originally.

Finally, the rest of the job will continue and may use any of the images pulled or built in previous steps. In this example tests are run using a `test-all` script.


```yaml
version: 2.1
orbs:
  docker-cache: cci-x/docker-registry-image-cache@0.2.0
workflows:
  ci:
    jobs:
      - build-docker-image
jobs:
  build-docker-image:
    machine:
      image: ubuntu-1604:201903-01
    steps:
      - run:
          name: docker login
          command: |
            echo "$REGISTRY_PASSWORD" | \
              docker login --username "$REGISTRY_USERNAME" --password-stdin https://us.gcr.io
      - docker-cache/with-save-restore-images:
          repository: us.gcr.io/myrepo
          images: myapp:${CIRCLE_BRANCH/\//-} myapp:master
          steps:
            - docker-cache/build:
                command: docker build -t myapp:${CIRCLE_BRANCH/\//-} .
      - run:
          name: Test
          command: ./test-all
```

### cache_using_branch_name_key_with_multistage

This example builds on cache_using_branch_name_key to demonstrate how to use this orb with Dockerfiles that use multi-stage builds.

The key thing to note is that you must build, cache, and restore each named stage of the build separately.

A Dockerfile with the intermediary stages base1 and base2 is assumed:

FROM ubuntu:latest AS base1
...
FROM base1 AS base2
...
FROM base2
...


```yaml
version: 2.1
orbs:
  docker-cache: cci-x/docker-registry-image-cache@0.2.0
workflows:
  ci:
    jobs:
      - build-docker-image
jobs:
  build-docker-image:
    machine:
      image: ubuntu-1604:201903-01
    steps:
      - run:
          name: docker login
          command: |
            echo "$REGISTRY_PASSWORD" | \
              docker login --username "$REGISTRY_USERNAME" --password-stdin https://us.gcr.io
      - docker-cache/with-save-restore-images:
          repository: us.gcr.io/myrepo
          parallelism: 4
          images: >-
            cache-orb:master cache-orb:base1-master cache-orb:base2-master
            cache-orb:${CIRCLE_BRANCH/\//-}
            cache-orb:base1-${CIRCLE_BRANCH/\//-}
            cache-orb:base2-${CIRCLE_BRANCH/\//-}
          steps:
            - docker-cache/build:
                command: >-
                  docker build -t cache-orb:base1-${CIRCLE_BRANCH/\//-} --target
                  base1 .
            - docker-cache/build:
                command: >-
                  docker build -t cache-orb:base2-${CIRCLE_BRANCH/\//-} --target
                  base2 .
            - docker-cache/build:
                command: docker build -t cache-orb:${CIRCLE_BRANCH/\//-} .
            - run:
                name: Test
                command: ./test-all
```

### cache_using_hash_of_dockerfile_key

This example demonstrates how to use this orb to speed up a 'docker build'. It uses the md5sum of the Dockerfile as a cache key. It follows all the same steps as the example above, except that it uses a different key for the cache. It assumes that an image with a 'latest' tag is pushed from the master CI job and can be used as a fallback when the Dockerfile changes.


```yaml
version: 2.1
orbs:
  docker-cache: cci-x/docker-registry-image-cache@0.2.0
workflows:
  ci:
    jobs:
      - build-docker-image
jobs:
  build-docker-image:
    machine:
      image: ubuntu-1604:201903-01
    steps:
      - run:
          name: docker login
          command: |
            echo "$REGISTRY_PASSWORD" | \
              docker login --username "$REGISTRY_USERNAME" --password-stdin
      - run:
          name: Generate cache key
          command: |
            md5sum Dockerfile | awk '{print $1}' > /tmp/cache-key
      - docker-cache/with-save-restore-images:
          repository: myhubrepo
          images: myapp:$(< /tmp/cache-key) myapp:latest
          steps:
            - docker-cache/build:
                command: docker build -t myapp:$(< /tmp/cache-key) .
      - run:
          name: Test
          command: ./test-all
```