GitHubActions에서 Docker를 빌드하고 ECS에 배포

16044 단어 GitHubActions도커ECS
CI/CD에는 Jenkins와 CircleCI도 있지만,
GitHubActions라는 것을 알고, GitHub를 사용하고 있다면 소스 코드와의 무결성도 유지해 편리하지 않을까 생각하고, 조속히 도입하기로 했습니다.
이번에는 GitHubActions에서 Docker를 빌드하고 ECS 클러스터에 갑자기 배포해 보겠습니다.

1.ECS 클러스터 생성



ECS 클러스터를 만듭니다.
※이 중에서는 클러스터명은, 「development」라고 하고 있습니다.

2.ECR 만들기



Docker Image를 등록하기 위한 ECR을 생성합니다.
이 중 ECR의 리포지토리 이름은 "development"입니다.

3.Dockerfile 만들기



예를 들어, 아래와 같은 PHP를 동작시키는 컨테이너를 Dockerfile을 만듭니다.
/deploy/development/docker/php/Dockerfile
FROM php:7.4-fpm-alpine

# JSTに変更
RUN apk add tzdata && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# PHP などインストール
RUN set -eux \
 && apk add --update --no-cache git autoconf g++ libtool make libzip-dev libpng-dev libjpeg-turbo-dev freetype-dev oniguruma-dev libxml2-dev sed nginx redis \
 && pecl install redis \
 && docker-php-ext-configure gd --with-jpeg=/usr/include/ --with-freetype=/usr/include/ \
 && docker-php-ext-configure opcache --enable-opcache \
 && docker-php-ext-install opcache pdo_mysql gd zip mbstring xml \
 && docker-php-ext-enable redis \
 && apk del autoconf g++ libtool make \
 && rm -rf /tmp/*

#フォルダコピー
COPY ./ /var/www/html

# 作業ディレクトリを変更
WORKDIR /var/www/html

#パーミッション変更
RUN chown -R www-data:www-data /var/www/html

#コンテナ起動時にphp-fpmとnginx実行
CMD php-fpm -D && nginx -g 'daemon off;'

4. AWS에서 배포를 위한 IAM 생성



AWS에서 ECS에 배포할 IAM 사용자를 만듭니다.
아래의 두 가지 권한 정책이 필요합니다.
· AmazonEC2ContainerRegistryFullAccess
· AmazonEC2ContainerServiceFullAccess


5. GitHub의 Actions secrets에서 AWS 배포를 위한 IAM 액세스 키 비밀 키 설정



GitHub의 리포지토리 → "Settings"→ "Secrets"에서 AWS 배포 액세스 키를 "AWS_ACCESS_KEY_ID", 비밀 키를 "AWS_SECRET_ACCESS_KEY"로 등록합니다.


6. ECS 클러스터의 태스크 정의 json 작성



ECS의 태스크 정의는 json 파일을 작성하여 awscli로 올려 둡시다.

deploy/development/ecs/ecs-task-definition.json
{
    "requiresCompatibilities": [
        "EC2"
    ],
    "inferenceAccelerators": [],
    "containerDefinitions": [
        {
            "name": "development",
            "image": "xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/development:latest",
            "memoryReservation": 350,
            "resourceRequirements": [],
            "essential": true,
            "portMappings": [
                {
                    "hostPort": 0,
                    "containerPort": 80,
                    "protocol": "tcp"
                }
            ],
            "environment": [],
            "environmentFiles": [],
            "secrets": [],
            "mountPoints": [],
            "volumesFrom": [],
            "extraHosts": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/development",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "ecs"
                }
            },
            "ulimits": [],
            "dockerLabels": {},
            "dependsOn": []
        }
    ],
    "volumes": [],
    "networkMode": "bridge",
    "placementConstraints": [],
    "family": "development",
    "taskRoleArn": "arn:aws:iam::xxxxxxxxxxxx:role/ecsTaskExecutionRole"
}

다음 명령을 사용하여 awscli에서 ECS 클러스터에 작업을 올려 둡니다.
aws ecs register-task-definition --cli-input-json file://./deploy/development/ecs/ecs-task-definition.json  --profile hogehogeplofile

※hogehogeplofile은 awscli의 프로파일. 자신의 프로필을 사용하십시오.

7.ECS 클러스터의 서비스 만들기



6의 작업 정의를 사용하여 서비스를 만드십시오.
json 파일을 만들고 awscli로 업할 수 있으며 AWS 콘솔에서도 좋습니다.

8. GitHubActions Workflow 구성 YAML 파일 작성



/.github/workflows/development-build-deploy.yml
on:
  push:
    branches:
      - development

name: Deploy to AmazonECS(development) from development branch

jobs:
  deploy:
    name: Deploy app
    runs-on: ubuntu-latest
    steps:

    - name: Checkout code
      uses: actions/checkout@v2

    - name: Configure AWS Credentials # AWSアクセス権限設定
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ap-northeast-1

    - name: Login to Amazon ECR # ECRログイン処理
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Build, tag, and push image to Amazon ECR # ECRイメージPush
      id: build-image
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: development
        IMAGE_TAG: ${{ github.sha }}
      run: |
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f ./deploy/development/docker/php/Dockerfile .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

    - name: Render Amazon ECS task definition # ECSタスク定義ファイルレンダリング
      id: render-container
      uses: aws-actions/amazon-ecs-render-task-definition@v1
      with:
        task-definition: deploy/development/ecs/ecs-task-definition.json # レポジトリ以下のタスク定義ファイルがあるPath
        container-name: development
        image: ${{ steps.build-image.outputs.image }}

    - name: Deploy to Amazon ECS service # ECSサービスデプロイ
      uses: aws-actions/amazon-ecs-deploy-task-definition@v1
      with:
        task-definition: ${{ steps.render-container.outputs.task-definition }}
        service: development-web
        cluster: development-cluster

이 코드는 GitHubActions 구성 파일입니다.

조건 : development에 Push되었을 때 아래 내용을 순차적으로 실행합니다.
①AWS 액세스 권한 설정
②ECR 로그인 처리
③Dockerfile에서 빌드하여 DockerImage를 작성하여 ECR에 Push
④ ECS 태스크 정의 재수정
⑤ ECS에 작업 정의를 사용하여 배포

9. 소스를 커밋하고 GitHub로 푸시하여 PullRequest를 실행합니다.



이제 준비가 되었으므로 Git에서 다른 브랜치로 커밋하십시오.
그리고 GitHub에 Push하고 PullRequest 내놓아 둡시다.

10. PullRequest로 병합하여 GitHubActions 실행



다른 브랜치 → development 브랜치에 병합하는 순간에 GitHubActions가 실행됩니다.
GitHub 리포지토리의 Actions 탭을 열어 실행 상태를 확인할 수 있습니다.


11. ECS의 롤링 업데이트가 끝날 때까지 기다린다.



GitHubActions에서 성공하면 ECS 클러스터에서 롤링 업데이트가 시작되므로 새 컨테이너가 될 때까지 기다리십시오.

좋은 웹페이지 즐겨찾기