I am building a CI/CD pipeline using Tekton on a bare metal Kubernetes Cluster. I have managed to cache the necessary images (Node & Nginx) and the layers, but how can I cache the .cache / public folders created by Gatsby build? These folders are not present in the repo. If the build step does not find these folders in takes longer because it needs to create all images using Sharp.
The pipeline has a PVC attached. In the task it is called source (workspaces). To be more clear, how can I copy the Gatsby folders to this PVC after the build has finished and to the Kaniko container before the next build?
The Tekton task has the following steps:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-docker-image
spec:
params:
- name: pathToDockerFile
type: string
description: The path to the dockerfile to build
default: $(resources.inputs.source-repo.path)/Dockerfile
- name: pathToContext
type: string
description: |
The build context used by Kaniko
(https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
default: $(resources.inputs.source-repo.path)
resources:
inputs:
- name: source-repo
type: git
outputs:
- name: builtImage
type: image
- name: event-to-sink
type: cloudEvent
workspaces:
# PVC
- name: source
description: |
Folder to write docker image digest
results:
- name: IMAGE-DIGEST
description: Digest of the image just built.
steps:
- name: kaniko-warmer
image: gcr.io/kaniko-project/warmer
workingDir: $(workspaces.source.path)
args:
- --cache-dir=$(workspaces.source.path)/cache
- --image=node:14-alpine
- --image=nginx:1.19.5
- name: print-date-unix-timestamp
image: bash:latest
script: |
#!/usr/bin/env bash
date | tee $(params.pathToContext)/date
- name: build-and-push
workingDir: $(workspaces.source.path)
image: gcr.io/kaniko-project/executor:v1.3.0
env:
- name: 'DOCKER_CONFIG'
value: '/tekton/home/.docker/'
command:
- /kaniko/executor
args:
- --build-arg=CACHEBUST=$(params.pathToContext)/date
- --dockerfile=$(params.pathToDockerFile)
- --destination=$(resources.outputs.builtImage.url)
- --context=$(params.pathToContext)
- --cache=true
- --cache-ttl=144h
- --cache-dir=$(workspaces.source.path)/cache
- --use-new-run
- --snapshotMode=redo
- --cache-repo=<repo>/kaniko-cache
- --log-timestamp
securityContext:
runAsUser: 0
- name: write-digest
workingDir: $(workspaces.source.path)
image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/imagedigestexporter:v0.16.2
command: ['/ko-app/imagedigestexporter']
args:
- -images=[{"name":"$(resources.outputs.builtImage.url)","type":"image","url":"$(resources.outputs.builtImage.url)","digest":"","OutputImageDir":"$(workspaces.source.path)/$(params.pathToContext)/image-digest"}]
- -terminationMessagePath=$(params.pathToContext)/image-digested
securityContext:
runAsUser: 0
- name: digest-to-result
workingDir: $(workspaces.source.path)
image: docker.io/stedolan/jq@sha256:a61ed0bca213081b64be94c5e1b402ea58bc549f457c2682a86704dd55231e09
script: |
cat $(params.pathToContext)/image-digested | jq '.[0].value' -rj | tee /$(results.IMAGE-DIGEST.path)
Dockerfile
FROM node:14-alpine as build
ARG CACHEBUST=1
RUN apk update \
&& apk add \
build-base \
libtool \
autoconf \
automake \
pkgconfig \
nasm \
yarn \
libpng-dev libjpeg-turbo-dev giflib-dev tiff-dev \
zlib-dev \
python \
&& rm -rf /var/cache/apk/*
EXPOSE 8000 9000
RUN yarn global add gatsby-cli
WORKDIR /usr/src/app
COPY ./package.json .
RUN yarn install
COPY . .
RUN yarn build && echo $CACHEBUST
CMD ["yarn", "serve"]
FROM nginx:1.19.5 as serve
EXPOSE 80
COPY --from=build /usr/src/app/public /usr/share/nginx/html
how can I cache the .cache / public folders created by Gatsby build? These folders are not present in the repo.
If Persistent Volumes is available on your cluster and these volumes is available from all nodes, you can use a PVC-backed workspace for cache.
A more generic solution that also works in a regional cluster (e.g. cloud) is to upload the cached folder to something, e.g. a Bucket (Minio?) or potentially Redis? Then also need a Task that download this folder - potentially in parallel with git clone
when starting a new PipelineRun
. GitHub Actions has a similar solution with the cache action.
Example of a Task with two workspaces that copy a file from one workspace to the other:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: copy-between-workspaces
spec:
workspaces:
- name: ws-a
- name: ws-b
steps:
- name: copy
image: ubuntu
script: cp $(workspaces.ws-a.path)/myfile $(workspaces.ws-b.path)/myfile