iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
IT Operation

從前後端踏上 AWS 雲端架構勇者之路系列 第 22 篇

ECR:把本機的 Docker Image 推上 AWS

  • 分享至 

  • xImage
  •  

上一篇我們把 Node.js 程式包成 Image,也在自己的電腦跑起來了。接下來要交給 EC2,這份 Image 要放哪裡,主機才拿得到?

這裡就要進入我們的主角,也就是 ECR(Elastic Container Registry) 哩,它是 AWS 用來保存容器 Image 的服務。今天把前篇的 demo-api:v1 推上去,下一篇再讓 EC2 下載,並且啟動它

要怎麼從自己的電腦,送到 EC2 主機

看下面這張圖:開發電腦把 Image push(上傳) 到 ECR,EC2 再 pull(下載) 同一份 Image 來執行,就不用每台主機各自下載程式,或者重新打包

https://ithelp.ithome.com.tw/upload/images/20261004/20040221lMFD7oWlYf.jpg

ECR 裡的 Repository(儲存庫) 用來放同一個應用的 Image。例如 demo-api 放我們的 API,再用 Tag(標籤) v1、v2 區分版本

圖裡右下角的 Container 才是正在執行的程式

建立 Private Repository

進入 AWS 的 ECR,區域選東京 ap-northeast-1,再到 Private registry → Repositories → Create repository:

  • 名稱:demo-api
  • Tag mutability:Immutable
  • Immutable tag exclusions:留空
  • 加密:保留預設 AES-256

確認後按 Create。或許你會想,網站要給大家看,為啥選 Private?

因為使用者是來使用網站,不是下載後端程式。Private 限制的是誰能拿到 Image,之後 EC2 的網站入口仍可以對外開放

那 Immutable 呢?假設今天的 v1 和明天的 v1 是不同內容,光看名稱,根本不知道主機跑哪一版。Immutable 會擋下同名 Tag 的覆寫,新內容就改用 v2,附上(ECR Tag 設定)

https://ithelp.ithome.com.tw/upload/images/20261004/20040221KvuUDKYKu0.jpg

建立後複製自己的 Repository URI,格式如下;YOUR_ACCOUNT_ID 要換成自己的 AWS 帳號 ID:

YOUR_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/demo-api

準備將 Image 推上去嘍~

接下來都在自己的電腦操作就好。先依 安裝說明 裝好 AWS CLI:Windows 選 MSI、macOS 選 PKG。重開終端機,執行 aws --version,就會看到 aws-cli/2...

AWS CLI 就是讓我們用 aws ... 指令操作 AWS 的工具。網頁登入過,不代表終端機也已登入;CLI 要知道你是誰,IAM 也要允許你上傳才行

準備上傳權限

可以用有 IAM 管理權限的身分建立專用 User:

  1. IAM → Policies → Create policy → JSON:貼上下方政策,把 YOUR_ACCOUNT_ID 換成自己的帳號 ID,命名 EcrPracticePush
  2. IAM → Users → Create user:名稱填 ecr-practice-pusher,不啟用 Console access,直接附加 EcrPracticePush
  3. 進這個 User 的 Security credentials → Access keys → Create access key,用途選 Command Line Interface (CLI),閱讀提示後建立,保存 ID/Secret
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ecr:GetAuthorizationToken",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability",
        "ecr:InitiateLayerUpload", "ecr:UploadLayerPart",
        "ecr:CompleteLayerUpload", "ecr:PutImage", "ecr:DescribeImages"
      ],
      "Resource": "arn:aws:ecr:ap-northeast-1:YOUR_ACCOUNT_ID:repository/demo-api"
    }
  ]
}

第一段允許取得 ECR 登入憑證,第二段把上傳與查詢限制在 demo-api。如果改了 Repository 名稱,政策最後那段也要跟著改(ECR 推送權限)

接下來就把身分設定到 AWS CLI 勒

剛建立練習 User 的人,在自己電腦執行:

aws configure --profile ecr-practice

依序填入:

CLI 問什麼 要填什麼
AWS Access Key ID ECR User 的 Key ID
AWS Secret Access Key 同一組 Secret
Default region name ap-northeast-1
Default output format json

ecr-practice 是本機這組設定的名字,稱為 profile。設定存在自己帳號的 .aws 資料夾,要記得含憑證的檔案不要放進 Git 或公開截圖,也附上(CLI 設定檔)

下方是 macOS/Linux 的指令:

export AWS_PROFILE=ecr-practice
export AWS_REGION=ap-northeast-1
aws sts get-caller-identity

export 讓目前終端機使用這組設定,重開視窗後要再設定。回傳的 Account 會是自己的帳號,Arn 要留意對上 ecr-practice-pusher

接著登入 ECR,下面的 REGISTRY 只替換 YOUR_ACCOUNT_ID,保留後面的網址;REPOSITORY_URI 接上 /demo-api:

REGISTRY=YOUR_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com
REPOSITORY_URI=$REGISTRY/demo-api

aws ecr get-login-password --region "$AWS_REGION" \
  | docker login --username AWS --password-stdin "$REGISTRY"

這段是 CLI 取得臨時登入憑證,再交給 Docker。--username AWS 的 AWS 照填。看到 Login Succeeded 就可以繼續往下做嘍

憑證有效 12 小時,到期再執行一次登入,也附上(ECR 登入方式)

接下就打包、標註後接著上傳

回到前篇放有 Dockerfile 的 demo-api 資料夾,確認 Docker 已啟動。後面要用 ARM64 的 EC2,所以這次明確指定 linux/arm64:

docker buildx build --platform linux/arm64 --load -t demo-api:v1 .
docker tag demo-api:v1 "$REPOSITORY_URI:v1"
docker push "$REPOSITORY_URI:v1"

這三行分別在做什麼呢?

  • build:打包成 ARM64 Image,--load 把結果放回本機 Docker
  • tag:替 Image 加上 ECR 的完整名稱,讓 Docker 知道要送去哪裡
  • push:實際上傳到 ECR

上傳後回 ECR → demo-api → Images,就可以看到 v1

點進去記下 Image digest,這是依內容算出的識別值,用來核對是不是同一份 Image

看這張圖就比較好認:地址由 Registry、Repository、Tag 組成;Digest 則用來認內容

https://ithelp.ithome.com.tw/upload/images/20261004/20040221kW3Z9fOJPH.jpg

也可以用 CLI 查這一版的 Tag、Digest 和上傳時間~

aws ecr describe-images --repository-name demo-api \
  --image-ids imageTag=v1 --region "$AWS_REGION" \
  --query 'imageDetails[0].{Tag:imageTags,Digest:imageDigest,PushedAt:imagePushedAt}'

假使有遇到「v1 已存在」,先查是不是剛剛已經推成功了。要上傳新內容,就把 build、tag、push 裡的 v1 一起改成 v2,也不用解除 Immutable

Windows PowerShell 操作方法

PowerShell 的變數寫法不同,Node.js 程式和 Dockerfile 都不用改。先完成前面的 CLI 身分設定,再進入 demo-api 資料夾,換好 profile 與帳號 ID以後請,逐行執行:

$env:AWS_PROFILE = 'ecr-practice'
$env:AWS_REGION = 'ap-northeast-1'
$Registry = 'YOUR_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com'
$RepositoryUri = "$Registry/demo-api"
aws sts get-caller-identity
aws ecr get-login-password --region $env:AWS_REGION | docker login --username AWS --password-stdin $Registry
docker buildx build --platform linux/arm64 --load -t demo-api:v1 .
docker tag demo-api:v1 "${RepositoryUri}:v1"
docker push "${RepositoryUri}:v1"

核對 Account/Arn,看到 Login Succeeded 再建置跟上傳,最後回 ECR 的 Images 找 v1 和 Digest

那 Intel/AMD 電腦也能做 ARM64 Image 嗎?Docker Desktop 支援跨架構建置,模擬執行可能比較慢

舊版本要留著嗎?

正在用的版本,以及出問題時要退回的版本,請都要保留勒

刪掉 ECR 的 Image 不會立刻停止正在跑的 Container,但換主機要重新下載時,就找不到了

Image 也會占儲存空間。累積太多可以用 Lifecycle policy 依照條件清理,套用前可以先跑 Preview,確認會刪哪些版本~

ECR 也有 Image scanning 檢查套件有沒有弱點。掃到問題就可以再更新套件,再打包部署嘍!附上(ECR 掃描文件)

小結

另外也提醒, ECR 在儲存與傳輸上也是有費用的~ 你可以看 ECR 計價方式

下一篇我們就把今天這份 Image 拉到 EC2,真的跑起來勒 :D


上一篇
Docker Image 是什麼?把程式打包後,再交給主機執行
系列文
從前後端踏上 AWS 雲端架構勇者之路 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言