🐳

GitLab-CIでECRビルドする

2024/06/29に公開

このドキュメントでは、GitLab-CIを使用してdockerイメージをビルドし、AWS ECRにプッシュする手順を紹介します。

コードは次のリポジトリにまとめられています:

https://gitlab.com/jokota-samples/gitlab-to-ecr

1. AWSにECRとIAMアカウントを作成する

最初にIAMユーザーを作成し、その後CloudFormationでECRを作成します。

IAMユーザーの作成
以下のテンプレートを使用してIAMユーザーを作成します(gitlab-user-cnf.yaml):

AWSTemplateFormatVersion: "2010-09-09"

Description: GitLab CI/CD User

Parameters:
  ProjectName:
    Type: String
    Default: ""

  EnvName:
    Type: String
    Default: ""

Resources:
  IAMUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${ProjectName}-${EnvName}-gitlab-user"
      Policies:
        - PolicyName: AllowPushImage
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ecr:BatchCheckLayerAvailability
                  - ecr:PutImage
                  - ecr:InitiateLayerUpload
                  - ecr:UploadLayerPart
                  - ecr:CompleteLayerUpload
                Resource:
                  - '*'
              - Effect: Allow
                Action:
                  - ecr:GetAuthorizationToken
                Resource:
                  - '*'

Outputs:
  MyUserArn:
    Value: !GetAtt IAMUser.Arn

ECRの作成

次にECRを作成するテンプレートを使用します(ecr-cfn.yaml):

AWSTemplateFormatVersion: "2010-09-09"

Description: ECR Repository

Parameters:
  ProjectName:
    Type: String
    Default: ""

  EnvName:
    Type: String
    Default: ""

  RepoName:
    Type: String
    Default: ""

  EcrPushUserArnList:
    Type: CommaDelimitedList
    Default: ""

Resources:
  MyRepository:
    Type: AWS::ECR::Repository
    Properties:
      EmptyOnDelete: true
      EncryptionConfiguration:
        EncryptionType: AES256
      ImageScanningConfiguration:
        ScanOnPush: true
      ImageTagMutability: IMMUTABLE
      RepositoryName: !Sub "${ProjectName}/${EnvName}/${RepoName}"
      RepositoryPolicyText:
        Version: "2012-10-17"
        Statement:
          - Sid: AllowPushPull
            Effect: Allow
            Principal:
              AWS: !Ref EcrPushUserArnList
            Action:
              - ecr:GetDownloadUrlForLayer
              - ecr:BatchGetImage
              - ecr:BatchCheckLayerAvailability
              - ecr:PutImage
              - ecr:InitiateLayerUpload
              - ecr:UploadLayerPart
              - ecr:CompleteLayerUpload

Outputs:
  MyRepositoryArn:
    Value: !GetAtt MyRepository.Arn

  MyRepositoryRepositoryUri:
    Value: !GetAtt MyRepository.RepositoryUri

2. GitLabにプロジェクトを作成する

まず、プロジェクトを作成します。

npx express-generator app
cd app
npm install
echo node_modules > .gitignore

動作確認のためにアプリケーションを起動します:

DEBUG=myapp:* npm start

3. Dockerfileを作成する

appフォルダにDockerfileを作成します:

FROM node:18
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]

4. gitlab-ci.ymlファイルを作成する

以下のgitlab-ci.ymlファイルを作成します:

stages:
  - build_and_push

default:
  before_script:
    - date_string=`echo ${CI_COMMIT_TIMESTAMP} | sed -e "s/T//g" -e "s/://g" -e "s/-//g" | cut -b 1-12`
    - branch_string=`echo ${CI_COMMIT_REF_NAME} | sed -e "s/\//-/g"`
    - ci_commit_tag=`echo ${CI_COMMIT_TAG} | sed -e "s/\//-/g"`
    - >
      if [ -n "$ci_commit_tag" ]; then
        export DOCKER_TAG=${ci_commit_tag}
      else
        export DOCKER_TAG=branch-${branch_string}-gitsha-${CI_COMMIT_SHORT_SHA}-${date_string}
      fi

build_and_push:
  stage: build_and_push
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind
  script:
    - apk add --update py-pip
    - pip install awscli
    - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
    - docker build -t ${AWS_ECR_URI}:${DOCKER_TAG} -f app/Dockerfile ./app/
    - docker push ${AWS_ECR_URI}:${DOCKER_TAG}
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

5. パイプラインの実行とECRの更新

GitLabのプロジェクト設定 > CI/CD > 変数に以下の環境変数を設定します:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_DEFAULT_REGION
  • AWS_ACCOUNT_ID
  • AWS_ECR_URI

これでgit pushすると自動でパイプラインが開始され、ECRにイメージがプッシュされます。

5. まとめ

以上が、GitLab-CIを使用してdockerイメージをビルドし、AWS ECRに自動でプッシュする方法の手順です。

Discussion