

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# “将 Docker 映像发布到亚马逊 ECR 镜像存储库” 示例 CodeBuild
<a name="sample-docker"></a>

该示例会生成一个 Docker 映像作为构建输出，然后将该 Docker 映像推送到 Amazon Elastic Container Registry (Amazon ECR) 映像存储库。您可以调整该示例以将 Docker 映像推送到 Docker Hub。有关更多信息，请参阅 [调整“将 Docker 映像发布到 Amazon ECR”示例，将其推送到 Docker Hub](sample-docker-docker-hub.md)。

要了解如何使用自定义 Docker 构建映像来构建 Docker 映像（Docker Hub 中的 `docker:dind`），请参阅我们的[自定义映像示例中的 Docker](sample-docker-custom-image.md)。

此示例参考 `golang:1.12` 进行了测试。

此示例使用新的多阶段 Docker 构建功能，该功能将生成一个 Docker 映像作为构建输出。然后，它将 Docker 映像推送到 Amazon ECR 映像存储库。多阶段 Docker 映像构建有助于减小最终 Docker 映像的大小。有关更多信息，请参阅[将多阶段构建和 Docker 结合使用](https://docs.docker.com/engine/userguide/eng-image/multistage-build/)。

**重要**  
运行此示例可能会导致您的 AWS 账户被扣款。其中包括与 Amazon S3、 AWS KMS、 CloudWatch 日志和 Amazon ECR 相关的 AWS 资源和操作可能产生的费用。 AWS CodeBuild 有关更多信息，请参阅[CodeBuild 定价](https://aws.amazon.com/codebuild/pricing)、[Amazon S3 定价](https://aws.amazon.com/s3/pricing)、[AWS Key Management Service 定价](https://aws.amazon.com/kms/pricing)、[亚马逊 CloudWatch 定价](https://aws.amazon.com/cloudwatch/pricing)和[亚马逊弹性容器注册表定价](https://aws.amazon.com/ecr/pricing)。

**Topics**
+ [运行“将 Docker 映像发布到 Amazon ECR”示例](#sample-docker-running)
+ [调整“将 Docker 映像发布到 Amazon ECR”示例，将其推送到 Docker Hub](sample-docker-docker-hub.md)

## 运行“将 Docker 映像发布到 Amazon ECR”示例
<a name="sample-docker-running"></a>

使用以下过程运行示例，将 Docker 映像发布到 Amazon ECR。有关此示例的更多信息，请参阅[“将 Docker 映像发布到亚马逊 ECR 镜像存储库” 示例 CodeBuild](#sample-docker)。

**要运行此示例，请执行以下操作：**

1. 如果 Amazon ECR 中已存在要使用的映像存储库，请跳至第 3 步。否则，如果您使用的是用户而不是 AWS 根账户或管理员用户来使用 Amazon ECR，请将此语句（介于*\$1\$1\$1 BEGIN ADDING STATEMENT HERE \$1\$1\$1*和之间*\$1\$1\$1 END ADDING STATEMENT HERE \$1\$1\$1*）添加到用户（或用户关联的 IAM 群组）。不建议使用 AWS 根账户。此语句允许创建用于存储 Docker 镜像的 Amazon ECR 存储库。为了简洁起见，也为了帮您查找添加语句的位置，此处使用了省略号 (`...`)。请勿删除任何语句，也不要将这些省略号键入策略中。有关更多信息，请参阅《用户指南》**中的[通过 AWS 管理控制台使用内联策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_inline-using.html#AddingPermissions_Console)。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "ecr:CreateRepository"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------
**注意**  
修改该策略的 IAM 实体必须拥有在 IAM 中修改策略的权限。

1. 在 Amazon ECR 中创建映像存储库。请务必在创建构建环境和运行构建的同一 AWS 区域创建存储库。有关更多信息，请参阅《Amazon ECR 用户指南》**中的[创建存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html)。该存储库的名称必须与您将在此过程的稍后部分指定的存储库名称相匹配，并以 `IMAGE_REPO_NAME` 环境变量的形式表示。确保 Amazon ECR 存储库策略为您的 CodeBuild服务 IAM 角色授予图片推送访问权限。

1. 将此语句（介于*\$1\$1\$1 BEGIN ADDING STATEMENT HERE \$1\$1\$1*和之间*\$1\$1\$1 END ADDING STATEMENT HERE \$1\$1\$1*）添加到您附加到 AWS CodeBuild 服务角色的策略中。此声明允许将 Docker 镜像上传 CodeBuild 到亚马逊 ECR 存储库。为了简洁起见，也为了帮您查找添加语句的位置，此处使用了省略号 (`...`)。请勿删除任何语句，也不要将这些省略号键入策略中。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "ecr:BatchCheckLayerAvailability",
                   "ecr:CompleteLayerUpload",
                   "ecr:GetAuthorizationToken",
                   "ecr:InitiateLayerUpload",
                   "ecr:PutImage",
                   "ecr:UploadLayerPart"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------
**注意**  
修改该策略的 IAM 实体必须拥有在 IAM 中修改策略的权限。

1. 按照本主题[目录结构](#sample-docker-dir)和[文件](#sample-docker-files)部分所述创建文件，然后将其上传到 S3 输入存储桶或 AWS CodeCommit GitHub、或 Bitbucket 存储库。有关更多信息，请参阅《AWS CodePipeline 用户指南》**中的[映像定义文件参考](https://docs.aws.amazon.com/codepipeline/latest/userguide/file-reference.html)。
**重要**  
请不要上传 `(root directory name)`，而只上传 `(root directory name)` 中的文件。  
如果您使用的是 S3 输入存储桶，请务必创建一个包含这些文件的 ZIP 文件，然后将其上传到输入存储桶。请不要将 `(root directory name)` 添加到 ZIP 文件中，而只添加 `(root directory name)` 中的文件。

1. 创建构建项目、运行构建和查看构建信息。

    如果您使用控制台创建项目：

   1.  对于**操作系统**，选择 **Ubuntu**。

   1.  对于**运行时**，选择**标准**。

   1.  **对于 “**图像**”，选择:5.0 aws/codebuild/standard。**

   1.  添加以下环境变量：
      +  AWS\$1DEFAULT\$1REGION 值为 *region-ID* 
      +  AWS\$1ACCOUNT\$1ID 值为 *account-ID* 
      +  具有最新值的 IMAGE\$1TAG 
      +  IMAGE\$1REPO\$1NAME 的值为 *Amazon-ECR-repo-name* 

   如果您使用创建构建项目，则`create-project`命令的 JSON 格式输入可能与此类似。 AWS CLI (请将占位符替换为您自己的值。)

   ```
   {
     "name": "sample-docker-project",
     "source": {
       "type": "S3",
       "location": "codebuild-region-ID-account-ID-input-bucket/DockerSample.zip"
     },
     "artifacts": {
       "type": "NO_ARTIFACTS"
     },
     "environment": {
       "type": "LINUX_CONTAINER",
       "image": "aws/codebuild/standard:5.0",
       "computeType": "BUILD_GENERAL1_SMALL",
       "environmentVariables": [
         {
           "name": "AWS_DEFAULT_REGION",
           "value": "region-ID"
         },
         {
           "name": "AWS_ACCOUNT_ID",
           "value": "account-ID"
         },
         {
           "name": "IMAGE_REPO_NAME",
           "value": "Amazon-ECR-repo-name"
         },
         {
           "name": "IMAGE_TAG",
           "value": "latest"
         }
       ],
     },
     "serviceRole": "arn:aws:iam::account-ID:role/role-name",
     "encryptionKey": "arn:aws:kms:region-ID:account-ID:key/key-ID"
   }
   ```

1. 确认 CodeBuild 已成功将 Docker 镜像推送到存储库：

   1. 打开 Amazon ECR 控制台，网址为[https://console.aws.amazon.com/ecr/](https://console.aws.amazon.com/ecr/)。

   1. 选择存储库名称。映像应在**映像标签**列中列出。

### 目录结构
<a name="sample-docker-dir"></a>

此示例采用以下目录结构。

```
(root directory name)
├── buildspec.yml
└── Dockerfile
```

### 文件
<a name="sample-docker-files"></a>

此示例将使用这些文件。

`buildspec.yml`（在 `(root directory name)`）

```
version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...          
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG      
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
```

`Dockerfile`（在 `(root directory name)`）

```
FROM golang:1.12-alpine AS build
#Install git
RUN apk add --no-cache git
#Get the hello world package from a GitHub repository
RUN go get github.com/golang/example/hello
WORKDIR /go/src/github.com/golang/example/hello
# Build the project and send the output to /bin/HelloWorld 
RUN go build -o /bin/HelloWorld

FROM golang:1.12-alpine
#Copy the build's output binary from the previous build container
COPY --from=build /bin/HelloWorld /bin/HelloWorld
ENTRYPOINT ["/bin/HelloWorld"]
```

**注意**  
CodeBuild 会替换自定义 Docker 镜像的。`ENTRYPOINT`