Home > OS >  Why docker image built locally and on github actions have different digest
Why docker image built locally and on github actions have different digest

Time:09-11

I am building and push docker image from github actions to AWS. Both locally and on gitHub, I use the same command to build the image; however, it results to different image digests.

Command I used:

docker buildx build --build-arg DOCKER_REGISTRY=$ECR_REGISTRY --platform=linux/amd64 -t "$ECR_REGISTRY/$ECR_REPO_NAME:$LATEST_TAG" -t "$ECR_REGISTRY/$ECR_REPO_NAME:$ECR_TAG" -f Dockerfile .

My Dockerfile:

FROM node:16

RUN apt-get update \
 && apt-get install -y chromium \
    fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \
    --no-install-recommends


RUN mkdir -p /usr/src/app
RUN chown -R node: /usr/src/app

USER node
WORKDIR /usr/src/app

COPY --chown=node:node  package.json package-lock.json /usr/src/app/

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
ENV PUPPETEER_EXECUTABLE_PATH /usr/bin/chromium
RUN npm config set registry https://registry.npmjs.org/
RUN npm install

# Copy crawl scripts
RUN mkdir -p /usr/src/app/scripts
RUN mkdir -p /usr/src/app/collected
COPY --chown=node:node lib/ /usr/src/app/lib/
COPY --chown=node:node scripts/ /usr/src/app/scripts/

CodePudding user response:

You're basing your image on a the node:16 image, which is a moving target. Depending on when you last pulled that image, you might actually be using node:16.8.0 or node:16.9.1.

Depending on which base image you start with, you're going to end up with a final image digest.

If you want to make absolutely sure you're building the same image in both environments, build using the digest rather than using a tag, e.g:

FROM node@sha256:0c672d547405fe64808ea28b49c5772b1026f81b3b716ff44c10c96abf177d6a

...

CodePudding user response:

Docker image builds from docker build and buildx are not reproducible (at least for now). Everything pushed to a registry is content addressable, referenced by the digest of the content itself. The image digest is from a json manifest that contains digests of various components, similar to a Merkle tree. If any of those components change, the top level digest also changes. And the components include things that change. Among the things that change are:

  • image creation time and time for each history step, there is a timestamp directly in the image config
  • file timestamps, which will be different if they are created at the time of the image build
  • base image, if you don't pin that base image to a digest
  • results of RUN steps, when those steps pull from external resources that give you the "latest" of some resource, e.g. apt-get install some_pkg will change every time the package or one of it's dependencies gets updated

I've been making efforts to modify an image after the fact, back dating timestamps, proxying all network requests, etc, but this is still pre-alpha and dependent on each image being built to find what changes between builds. For some of the debugging using regctl I've been adding regctl manifest diff, regctl blob diff-config, and regctl blob diff-layer. And then to change the image, there's an experimental regctl image mod command.

  • Related