如何让我的 Dockerfile 使用来自 ECR 注册表而不是 Dockerhub 的基础映像?

How do I make my Dockerfile use base images from ECR registry instead of Dockerhub?

我有一个 Codebuild 项目,它正在构建一个 docker 图像并将其推送到 ECR 注册表。我遇到了 dockerhub 速率限制,所以我一直在尝试从 AWS ECR Gallery 而不是 Dockerhub 中提取相同的图像。我如何强制 docker 构建使用拉取的图像,而不是使用来自 docker 集线器注册表的标签重新下载相同的图像?

Codebuild buildspec.yaml

version: 0.2
phases: 
  install:
    runtime-versions:
        docker: 19     
    commands: 
      - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2&
      - timeout 15 sh -c "until docker info; do echo .; sleep 1; done"
  pre_build: 
    commands: 
    - echo Logging in to Amazon ECR.... 
    - aws --version
    # update the following line with your own region
    - $(aws ecr get-login --no-include-email --region us-east-1)
    - IMAGE_TAG=$Environment
    - REPOSITORY_URI=<removing-this-part-was-my-private-repository-uri>
    - echo Pushing to $REPOSITORY_URI:$IMAGE_TAG
    - docker pull public.ecr.aws/docker/library/node:14.19.0-alpine3.14
    - docker pull public.ecr.aws/nginx/nginx:alpine
  build: 
    commands: 
    - echo Build started on `date` 
    - echo Building the Docker image... 
    # update the following line with the name of your own ECR repository
    - docker build -t local_build:latest .
    # update the following line with the URI of your own ECR repository (view the Push Commands in the console)
    - docker tag local_build:latest $REPOSITORY_URI:$IMAGE_TAG 
  post_build: 
    commands: 
    - echo Build completed on `date` 
    - echo pushing to repo
    # update the following line with the URI of your own ECR repository
    - docker push $REPOSITORY_URI:$IMAGE_TAG

如您所见,我正在从 ECR public 图库中提取 node:14.19.0-alpine3.14nginx:alpine 图像。

这是我的 Dockerfile:

# Multi-stage
# 1) Node image for building frontend assets
# 2) nginx stage to serve frontend assets

# Name the node stage "builder"
FROM node:14.19.0-alpine3.14 AS builder
# Some build tools here 
RUN apk add g++ make py3-pip
# Set working directory
WORKDIR /app
# Copy all files from current directory to working dir in image
COPY . .
# install node modules and build assets
RUN npm ci && npm run build

# nginx state for serving content
FROM nginx:alpine
# Set working directory to nginx asset directory
WORKDIR /usr/share/nginx/html
# Remove default nginx static assets
RUN rm -rf ./*
# Copy static assets from builder stage
COPY --from=builder /app/build .
# Containers run nginx with global directives and daemon off
ENTRYPOINT ["nginx", "-g", "daemon off;"]

代码构建日志:

[Container] 2022/02/08 04:49:19 Running command docker pull public.ecr.aws/docker/library/node:14.19.0-alpine3.14
113 14.19.0-alpine3.14: Pulling from docker/library/node
114 97518928ae5f: Pulling fs layer
115 94ae0bc29be1: Pulling fs layer
116 d5329011e23a: Pulling fs layer
117 b0eb5127ee8f: Pulling fs layer
118 b0eb5127ee8f: Waiting
119 d5329011e23a: Download complete
120 97518928ae5f: Verifying Checksum
121 97518928ae5f: Download complete
122 b0eb5127ee8f: Verifying Checksum
123 b0eb5127ee8f: Download complete
124 97518928ae5f: Pull complete
125 94ae0bc29be1: Download complete
126 94ae0bc29be1: Pull complete
127 d5329011e23a: Pull complete
128 b0eb5127ee8f: Pull complete
129 Digest: sha256:8c93166ecea91d8384d9f1768ceaca1cd8bc22c1eb13005cecfb491588bd8169
130 Status: Downloaded newer image for public.ecr.aws/docker/library/node:14.19.0-alpine3.14
131 public.ecr.aws/docker/library/node:14.19.0-alpine3.14
132 
133 [Container] 2022/02/08 04:49:24 Running command docker pull public.ecr.aws/nginx/nginx:alpine
134 alpine: Pulling from nginx/nginx
135 59bf1c3509f3: Pulling fs layer
136 8d6ba530f648: Pulling fs layer
137 5288d7ad7a7f: Pulling fs layer
138 39e51c61c033: Pulling fs layer
139 ee6f71c6f4a8: Pulling fs layer
140 f2303c6c8865: Pulling fs layer
141 39e51c61c033: Waiting
142 ee6f71c6f4a8: Waiting
143 f2303c6c8865: Waiting
144 5288d7ad7a7f: Download complete
145 39e51c61c033: Verifying Checksum
146 39e51c61c033: Download complete
147 59bf1c3509f3: Verifying Checksum
148 59bf1c3509f3: Download complete
149 ee6f71c6f4a8: Verifying Checksum
150 ee6f71c6f4a8: Download complete
151 f2303c6c8865: Verifying Checksum
152 f2303c6c8865: Download complete
153 8d6ba530f648: Verifying Checksum
154 8d6ba530f648: Download complete
155 59bf1c3509f3: Pull complete
156 8d6ba530f648: Pull complete
157 5288d7ad7a7f: Pull complete
158 39e51c61c033: Pull complete
159 ee6f71c6f4a8: Pull complete
160 f2303c6c8865: Pull complete
161 Digest: sha256:3f033ffbe255618d38a47a4909f257c66620e08ce7b50f4081f16ca09c2cb74f
162 Status: Downloaded newer image for public.ecr.aws/nginx/nginx:alpine
163 public.ecr.aws/nginx/nginx:alpine
164 
165 [Container] 2022/02/08 04:49:26 Phase complete: PRE_BUILD State: SUCCEEDED
166 [Container] 2022/02/08 04:49:26 Phase context status code:  Message: 
167 [Container] 2022/02/08 04:49:26 Entering phase BUILD
168 [Container] 2022/02/08 04:49:26 Running command echo Build started on `date`
169 Build started on Tue Feb 8 04:49:26 UTC 2022
170 
171 [Container] 2022/02/08 04:49:26 Running command echo Building the Docker image...
172 Building the Docker image...
173 
174 [Container] 2022/02/08 04:49:26 Running command docker build -t depaint:latest .
175 Sending build context to Docker daemon  2.353MB
176 
177 Step 1/10 : FROM node:14.19.0-alpine3.14 AS builder
178 14.19.0-alpine3.14: Pulling from library/node
179 Digest: sha256:8c93166ecea91d8384d9f1768ceaca1cd8bc22c1eb13005cecfb491588bd8169
180 Status: Downloaded newer image for node:14.19.0-alpine3.14
181  ---> 442800913bae

这里的179-181行好像证明反正又重新下载了

我还尝试将 docker 内部的构建命令 buildspec.yaml 更改为:

docker build -t <name-removed>:latest --cache-from public.ecr.aws/docker/library/node:14.19.0-alpine3.14 --cache-from public.ecr.aws/nginx/nginx:alpine .

这个也没用

问题出在这里:

FROM node:14.19.0-alpine3.14 AS builder

您尚未在此 FROM 语句中指定注册表。由于您尚未指定注册表,因此它会提取 hub.docker.com/docker/library/node。这是与 public.ecr.aws/docker/library/node:14.19.0-alpine3.14 不同的标签,因为所有注册表都有不同的命名空间。

如果你想要来自 ECR 的版本,你需要在你的 Dockerfile 中指定:

FROM public.ecr.aws/docker/library/node:14.19.0-alpine3.14

这也使得在构建之前无需拉取基础镜像 - 如果基础镜像不存在,它会自动获取。