英文:
CircleCI Docker ECR orb ERROR: failed to solve: failed to compute cache key: "/init.sh" not found
问题
I am utilizing CircleCI and ECR orb to build my docker image and push it to Elastic Container Registry (ECR) but I keep running into the following error: ERROR: failed to solve: failed to compute cache key: "/init.sh" not found
.
My directory structure is as follows:
Terraform
.circleci
infra
frontend
--- Dockerfile
--- init.sh
So basically I have a Terraform directory. Inside that directory I have an infra
directory and a frontend
directory. The frontend directory consists of my Dockerfile
and my init.sh
script.
The contents of my Dockerfile is as follows:
FROM node:14
ENV JQ_VERSION=1.6
RUN wget --no-check-certificate https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-linux64 -O /tmp/jq-linux64
RUN cp /tmp/jq-linux64 /usr/bin/jq
RUN chmod +x /usr/bin/jq
WORKDIR /app
COPY . .
RUN jq 'to_entries | map_values({ (.key) : ("$" + .key) }) | reduce .[] as $item ({}; . + $item)' ./src/config.json > ./src/config.tmp.json && mv ./src/config.tmp.json ./src/config.json
RUN npm install && npm run build
FROM nginx:1.17
ENV JSFOLDER=/usr/share/nginx/html/js/*.js
COPY ./init.sh /usr/bin/init.sh
RUN chmod +x /usr/bin/init.sh
WORKDIR /usr/share/nginx/html
COPY --from=0 /app/dist .
ENTRYPOINT ["init.sh"]
and my CircleCI config has the following content:
version: '2.1'
orbs:
aws-ecr: circleci/aws-ecr@8.2.1
aws-cli: circleci/aws-cli@3.1
jobs:
build:
machine:
image: ubuntu-2004:2022.10.1
steps:
- checkout
- aws-ecr/build-and-push-image:
repo: frontend
push-image: true
region: ${AWS_REGION}
registry-id: REGISTRY_ID
dockerfile: frontend/Dockerfile
path: .
tag: ${CIRCLE_SHA1}
workflows:
test:
jobs:
- build:
But CircleCI gives me the following error:
[stage-1 2/5] COPY ./init.sh /usr/bin/init.sh:
ERROR: failed to solve: failed to compute cache key: "/init.sh" not found: not found
Exited with code exit status 1
英文:
I am utilizing CircleCI and ECR orb to build my docker image and push it to Elastic Container Registry ( ECR ) but I keep running into the following error: ERROR: failed to solve: failed to compute cache key: "/init.sh" not found
.
My directory structure is as follows:
Terraform
.circleci
infra
frontend
--- Dockerfile
--- init.sh
So basically I have a Terraform directory. Inside that directory I have an infra
directory and a frontend
directory. The frontend directory consists of my Dockerfile
and my init.sh
script.
The contents of my Dockerfile is as follows:
FROM node:14
ENV JQ_VERSION=1.6
RUN wget --no-check-certificate https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-linux64 -O /tmp/jq-linux64
RUN cp /tmp/jq-linux64 /usr/bin/jq
RUN chmod +x /usr/bin/jq
WORKDIR /app
COPY . .
RUN jq 'to_entries | map_values({ (.key) : ("$" + .key) }) | reduce .[] as $item ({}; . + $item)' ./src/config.json > ./src/config.tmp.json && mv ./src/config.tmp.json ./src/config.json
RUN npm install && npm run build
FROM nginx:1.17
ENV JSFOLDER=/usr/share/nginx/html/js/*.js
COPY ./init.sh /usr/bin/init.sh
RUN chmod +x /usr/bin/init.sh
WORKDIR /usr/share/nginx/html
COPY --from=0 /app/dist .
ENTRYPOINT [ "init.sh" ]
and my CircleCI config has the following content:
version: '2.1'
orbs:
aws-ecr: circleci/aws-ecr@8.2.1
aws-cli: circleci/aws-cli@3.1
jobs:
build:
machine:
image: ubuntu-2004:2022.10.1
steps:
- checkout
- aws-ecr/build-and-push-image:
repo: frontend
push-image: true
region: ${AWS_REGION}
registry-id: REGISTRY_ID
dockerfile: frontend/Dockerfile
path: .
tag: ${CIRCLE_SHA1}
workflows:
test:
jobs:
- build:
But CircleCI gives me the following error:
> [stage-1 2/5] COPY ./init.sh /usr/bin/init.sh:
------
ERROR: failed to solve: failed to compute cache key: "/init.sh" not found: not found
Exited with code exit status 1
答案1
得分: 0
以下是要翻译的内容:
"It requires reading and understanding of the error message (and yes a little bit of discipline if it is all-new as we're easily distracted in complex computer systems):
ERROR: failed to solve: failed to compute cache key: "/init.sh" not found: not found
The message result is at the end, the operation in front, separator is :
. Additionally the message is prefixed by its class (ERROR).
More structural:
Error: failed to solve
- failed to compute cache key
- "/init.sh" not found
- not found
If you're coming from development, compare it a bit with a backtrace, but you need to throw a bit more brain on it as we don't have file paths and line numbers (not even binary offsets) here.
For me, for example, it is that 2. and 3. tell me "not found" is a file not found. As this is within Dockerfile (or Docker build) context, we can spot one operation already, as we know it involves files and a real file-system that could give such I/O errors:
COPY ./init.sh /usr/bin/init.sh
Then I'd read-up the manual for COPY to understand a bit better why the message tells it is "/init.sh" (absolute path) while within the COPY directive it is "./init.sh" (relative path). I may not understand it within three minutes; therefore, I skip with this knowledge and know that I only assume it is a match.
Then, given it is a match, I look into its CircleCI binding:
- aws-ecr/build-and-push-image:
repo: frontend
push-image: true
region: ${AWS_REGION}
registry-id: REGISTRY_ID
dockerfile: frontend/Dockerfile
path: .
tag: ${CIRCLE_SHA1}
Again, we need to get into the know, and that is finding the reference for the CircleCI Orb and its command in question: aws-ecr/build-and-push-image. Without it, we have no reference and aren't able to gather any meaning (just to guess it, but who needs brute force all the time? The strong weak!).
As our first assumption is this is file-system related, we can perhaps identify the "dockerfile" and "path":
dockerfile: Name of the dockerfile to use. Defaults to Dockerfile.
REQUIRED: No DEFAULT: Dockerfile TYPE: string
path: Path to the directory containing your Dockerfile. Defaults to . (working directory).
REQUIRED: No DEFAULT: . TYPE: string
You then lay all those three pieces of information one after another:
ERROR: failed to solve: failed to compute cache key: "/init.sh" not found: not found
COPY ./init.sh /usr/bin/init.sh
dockerfile: frontend/Dockerfile
path: .
Comparing this information against the actual project file layout, the cause of the error is now relatively easy to spot: there is no such file "./init.sh".
And it is now relatively easy to bind the correct path, as we knew it from the beginning:
COPY ./frontend/init.sh /usr/bin/init.sh
Learn how to treat error messages with respect; they have a story to tell, despite how bad or hard to read they may appear. Always remember it is the best you'll get. And I always look up the references. If I don't know where the reference is, at least (and expressing that knowledge with a URL is reasonably adequate for distributed systems), I'm often doing the wrong step first. It must not be that I fully understand the system, but I need to know about what I know and what I do not know so I can slow down the moving target that decided to run away and give us an error at least. Troubleshooting 1x1.
And as we have all parts under version control here (if you don't, do that first), those hypertext references are easy to add to the commit message, which should document the driver of the change (the error message) and how we think the change addresses it (and c.f. Beams):
original error message
git reference since when it was introduced
and fix attempt rationale
And just a final note: When we have fixed the error, it is easy (or easier) to say what the cause was. So in the moment of the commit and putting it to test, we can only document our little understanding. However, it is important to at least document it so that even steep learning curves can be taken without losing track and going in all fresh each time of an error in (remote) CI. Feedback is too often slow to waste time with staying in the unknown. You should always only apply a fix by having the rationale of it a priori, with perhaps the exclusion that if it takes longer than three minutes - which in remote CI means it must be a single commit that did run through and was tested working within that three minutes time if you want to make a good rule of thumb out of it<sup> 3</sup>.
COPY that .
- COPY Dockerfile reference https://docs.docker.com/engine/reference/builder/#copy
- aws-ecr/build-and-push-image CircleCI Orb https://circleci.com/developer/orbs/orb/circleci/aws-ecr#commands-build-and-push-image
- I sadly don't have the reference for the three-minute guess-time in debugging at hand; basically, how I understand it here, it means you should not guess longer than only a short time (like 3 minutes) while debugging but answer all your own questions before you question the system or others that configured it (asking for help is fine, cooperation is key). Also, there is the Golden Rule https://en.wikipedia.org/wiki/Golden_Rule.
英文:
It requires reading and understanding of the error message (and yes a little bit of discipline if it is all-new as we're easily distracted in complex computer systems):
> ERROR: failed to solve: failed to compute cache key: "/init.sh" not found: not found
The message result is at the end, the operation in front, separator is :
. Additionally the message is prefixed by its class (ERROR
).
More structural:
Error: failed to solve
- failed to compute cache key
- "/init.sh" not found
- not found
If you're coming from development, compare it a bit with a backtrace, but you need to throw a bit more brain on it as we don't have file paths and line numbers (not even binary offsets) here.
For me for example, it is that 2. and 3. tell me "not found" is a file not found. As this is within Dockerfile (or Docker build) context, we can spot one operation already, as we know it involves files and a real file-system that could give such I/O errors:
COPY ./init.sh /usr/bin/init.sh
Then I'd read-up the manual for COPY
<sup> 1</sup> to understand a bit better why the message tells it is /init.sh
(absolute path) while within the COPY
directive it is ./init.sh
(relative path). I may not understand it within three minutes therefore I skip with this knowledge and know that I only assume it is a match.
Then given it is a match I look into its circelci binding:
- aws-ecr/build-and-push-image:
repo: frontend
push-image: true
region: ${AWS_REGION}
registry-id: REGISTRY_ID
dockerfile: frontend/Dockerfile
path: .
tag: ${CIRCLE_SHA1}
Again, we need to get into the know and that is finding the reference for the CircleCI Orb and its command in question: aws-ecr/build-and-push-image
<sup>2</sup>. Without it, we have no reference and aren't able to gather any meaning (just to guess it, but who needs brute force all the time? The strong weak!).
As our first assumption is this is file-system related we can perhaps identify the dockerfile
and path
:
> dockerfile
: Name of dockerfile to use. Defaults to Dockerfile.
>
> REQUIRED: No DEFAULT: Dockerfile TYPE: string
>
> path
: Path to the directory containing your Dockerfile. Defaults to . (working
directory).
>
> REQUIRED: No DEFAULT: . TYPE: string
>
You then lay all those three piece of information one after another:
ERROR: failed to solve: failed to compute cache key: "/init.sh" not found: not found
COPY ./init.sh /usr/bin/init.sh
dockerfile: frontend/Dockerfile
path: .
Comparing this information against the actual project file layout, the cause of error is now relatively easy to spot: there is no such file ./init.sh
.
And it is now relatively easy to bind the correct path, as we knew it from the beginning:
COPY ./frontend/init.sh /usr/bin/init.sh
Learn on how to treat error messages with respect, they have a story to tell, despite how bad/or hard to read they may appear, always remember it is the best you'll get. And I always look up the references. If I dunno where the reference is at least (and expressing that knowledge with a URL is reasonable adequate for distributed systems), I'm often doing the wrong step first. It must not that I fully understand the system, but I need to know about what I know and what I not know about so I can slow down the moving target that decided to ran away and giving us an error at least. Trouble shooting 1x1.
And as we have all parts under version control here (if you don't, do that first), those hypertext references are easy to add to the commit message, which should document the driver of the change (the error message) and how we think the change addresses it (and c.f. Beams):
- original error message
- git reference since when it was introduced
- and fix attempt rationale
And just a final note: When we have fixed the error, it is easy (or easier) to say what the cause was. So in the moment of the commit and putting it to test, we can only document our little understanding. However it is important to at least document it so that even steep learning curves can be taken without loosing track and going in all fresh each time of an error in (remote) CI. Feedback is too often slow to waste time with staying in the unknown. You should always only apply a fix by having the rationale of it a priori, with perhaps the exclusion that if it takes longer than three minutes - which in remote CI means it must be a single commit that did run through and was tested working within that three minutes time if you want to make a good rule of thumb out of it<sup> 3</sup>.
> COPY that .
- COPY Dockerfile reference https://docs.docker.com/engine/reference/builder/#copy
- aws-ecr/build-and-push-image CircleCI Orb https://circleci.com/developer/orbs/orb/circleci/aws-ecr#commands-build-and-push-image
- I sadly don't have the reference for the three minute guess-time in debugging at hand, basically how I understand it here it means you should not guess longer than only a short time (like 3 minutes) while debugging but answer all your own questions before you question the system or others that configured it (asking for help is fine, cooperation is key). Also there is the Golden Rule https://en.wikipedia.org/wiki/Golden_Rule.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论