You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab CI中docker login登录AWS ECR失败如何排查解决

GitLab CI 推送镜像至AWS ECR时docker login执行失败修复方案

报错根因

三个登录命令的报错原因分别如下:

  • 带-p参数直接传密码的命令返回Denied: not authorized:你通过py-pip安装的是1.x版本的awscli,get-login-password是awscli 2.x版本才支持的接口,旧版本执行该命令不会返回有效授权令牌,直接传空/错误值给docker就会报无权限。另外你单独执行的aws ecr get-login --no-include-email是1.x版本的旧命令,执行后会直接输出完整的docker login执行语句,你没有执行该语句的输出内容,这行配置完全无效。
  • 两个带--password-stdin参数的命令返回Cannot perform an interactive login from a non TTY device:使用该参数时必须通过标准输入传入密码,你没有通过管道把密码传给docker进程,docker在非交互的CI环境下等不到密码输入就会直接抛出该错误。
  • 额外隐性问题:你当前配置没有指定DOCKER_HOST变量,docker客户端可能无法正常连接dind服务,会触发额外的连接类报错;原配置中注册ECS任务定义的命令写错了服务名,把ecs写成了ecr,执行时也会报错。

修复步骤

  • 替换awscli安装源:不要通过pip安装旧版awscli,直接用alpine官方源内置的awscli 2.x版本,避免版本兼容问题。
  • 修正docker login写法:通过管道把aws ecr get-login-password的输出传给docker login的标准输入,不要单独使用--password-stdin参数。
  • 校验AWS权限:确认GitLab CI中配置的AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY对应的身份(或OIDC关联角色)持有以下ECR权限:ecr:GetAuthorizationToken、ecr:BatchCheckLayerAvailability、ecr:InitiateLayerUpload、ecr:UploadLayerPart、ecr:CompleteLayerUpload、ecr:PutImage,跨账号推送时还要额外确认目标ECR仓库的资源策略允许当前身份推送。
  • 补充dind必要配置:添加DOCKER_HOST变量指向dind服务,如遇TLS证书报错可加DOCKER_TLS_CERTDIR: ""关闭TLS校验(仅内网CI环境可用)。

修正后的配置参考

image: docker:latest

services:
  - docker:dind

variables:
  DOCKER_HOST: tcp://docker:2376
  DOCKER_TLS_CERTDIR: "/certs"
  AWS_REGION: us-west-2
  PRIVATE_ECR_REGISTRY: 775362094965.dkr.ecr.us-west-2.amazonaws.com
  # 公有ECR登录必须指定us-east-1区域
  # PUBLIC_ECR_REGISTRY: public.ecr.aws/u1c1h9j4

before_script:
  - apk add --update --no-cache jq awscli
  # 登录私有ECR
  - aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $PRIVATE_ECR_REGISTRY
  # 如需登录公有ECR放开下面注释
  # - aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin $PUBLIC_ECR_REGISTRY

stages:
  - build
  - deploy

build-job:
  stage: build
  script:
    - docker build -t $PRIVATE_ECR_REGISTRY/$REPOSITORY_URL:$IMAGE_TAG .
    - docker push $PRIVATE_ECR_REGISTRY/$REPOSITORY_URL:$IMAGE_TAG
  only:
    - main

deploy-job:
  stage: deploy
  script:
    - aws ecs describe-task-definition --task-definition $CI_AWS_ECS_TASK_DEFINITION --region $AWS_REGION > input.json
    - cat input.json | jq '.taskDefinition.containerDefinitions[].image="'$PRIVATE_ECR_REGISTRY'/'$REPOSITORY_URL':'$IMAGE_TAG'"' | jq '.taskDefinition' > input.json
    - cat input.json | jq 'del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)' > input.json
    - aws ecs register-task-definition --cli-input-json file://input.json --region $AWS_REGION
    - revision=$(aws ecs describe-task-definition --task-definition $CI_AWS_ECS_TASK_DEFINITION --region $AWS_REGION | jq -r '.taskDefinition.revision')
    - aws ecs update-service --cluster $CI_AWS_ECS_CLUSTER --service $CI_AWS_ECS_SERVICE --task-definition $CI_AWS_ECS_TASK_DEFINITION:$revision --region $AWS_REGION

额外注意事项

  • 镜像地址不要带https://前缀,直接写注册表域名即可。
  • 公有ECR的登录接口全局部署在us-east-1区域,不管你实际仓库在哪个区域,登录公有ECR时必须指定--region us-east-1,否则会报域名解析错误或权限错误。
  • 不建议使用长期AK/SK,优先配置GitLab与AWS的OIDC身份提供商,用临时角色凭证访问ECR,避免密钥泄露风险。

内容的提问来源于stack exchange,提问作者MP32

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 11:57:21