[AWS] 도커와 깃 액션을 이용해서 백엔드 배포하기 - EC2, EB, Docker, GitAction
프로젝트 배포를위해, 컨 게시글에서 프론트 페이지를 먼저 배포하였다.
이제 백엔드 쪽을 배포할 건데, Docker 와 GitAction을 사용하여, ElasticBeanstalk를 이용해서 배포할려고 한다.
ElasticBeanstalk를 이용하면, ELB + Auto Scaling + EC2 한번에 관리할 수 있다.
아래의 게시글 따라하며, EB를 구성하는데,
EB의 플랫폼을 도커로 설정하여 만들어줘야한다.
EB 생성
https://thalals.tistory.com/151
EB를 사용하지 않고 하나씩 만들어줄 때
https://thalals.tistory.com/150
EB생성시 에러
error code : Environment health has transitioned from Pending to Severe. ELB processes are not healthy on all instances. Initialization in progress (running for 11 minutes). None of the instances are sending data. ELB health is failing or not available for all instances.
EB생성시 이런 에러가 나왔는데, 구글링을 해보니 VPC와 EC2의 통신이 원할하지 않다,, 머 이런 뜻으로 보이는 글들이 많았다.. 이거저거 해보다가 결국 튜터님에게 물어보니
라우팅 테이블이 잘못되어있었다고 한다.
라우팅 테이블을 깨끗하게 정리하고, 정상적인거 하나만 남겨두었더니 해결되었다,, 난 언제쯤 혼자서 이런 에러를 잡을 수 잇을까 후
결론
이런 에러가 나오면, VPC 와, 라우팅테이블, 서브넷을 살표보자
GitAction으로 EB 자동 배포하기
이제 GitAction을 사용해보자
GitAction 이란,
- 소프트웨어 workflow를 자동화할 수 있도록 도와주는 도구
- workflow란 여러 job으로 구성되고, Event에 의해 트리거가 될 수 있는 자동화된 프로세스
- Workflow 파일은 YAML으로 작성되고, Github Repository의 .github/workflows 폴더 아래에 저장된다.
Workflow 구조,
- Event - workflow를 실행하는 특정 활동이나 규칙
- 특정 브랜치로 Push하거나
- 특정 브랜치로 Pull Request하거나
- 특정 시간대에 반복(Cron)
- Webhook을 사용해 외부 이벤트를 통해 실행
- Job - Job은 여러 step으로 구성되고, 가상 환경의 인스턴스에서 실행됨
- 다른 Job에 의존 관계를 가질 수 있고, 독립적으로 병렬 실행도 가능하다.
- Step - Task들의 집합으로, 커맨드를 날리거나 action을 실행할 수 있다.
- Action
- Workflow의 가장 작은 블럭
- Job을 만들기 위해 Step들을 연결할 수 있다.
- 재상용이 가능한 컴포넌트
- 개인적으로 만든 Action을 사용할 수 도 있고, Marketplace에 있는 공용 Action을 사용할 수도 있다.
- Runner
- Gitbub Action Runner 어플리케이션이 설치된 머신으로, Workflow가 실행될 인스턴스
- Github에서 호스팅해주는 Github-hosted runner와 직접 호스팅하는 Self-hosted runner로 나뉨
- Github-hosted runner는 Azure의 Standard_DS2_v2로 vCPU 2, 메모리 7GB, 임시 스토리지 14GB
1. 먼저 IAM 사용자에 권한을 추가해준다.
2. EB 환경 속성 추가
- EB에 환경변수 설정 - 구성 > 소프트웨어 수정 > 환경속성
그 다음 이렇게 EB저장된 환경변수를 사용할 수있는데, 배포를 하지 않은 로컬환경에서는 로컬환경에 환경변수를추가해주어야한다.
3. 인텔리제이에서 환경변수 추가하기
[Run] - [Edit configuration] - Run/debug configurations
이렇게 하면 로컬에서 실행할 때는, 여기있는 환경변수 값으로,
EB 배포환경에서는 EB환경변수 값이 들어간다.
4. GitAction 으로 배포하기
workflow.yml 쉘 스크립트 파일을 특정 폴더안에 위치시키면, 깃에 올릴때 깃에서 읽어 해당 내용을 실행한다.
- 기본적인 방법 : .github/worfklows 폴더 안에 .yml 파일을 생성 => 템플릿 활용하면 좋음
- Github Repo에서 Actions 클릭
.github/workflows/docker.workflow.yml
secrets.ACCESS_KEY_ID와 secrets.ACCESS_KEY_SECRET는 Github의 Secrets을 통해 넣어준 값
name: Build and Push Docker Image
on:
push:
branches:
- main
jobs:
build-and-push-image:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean build
- name: Configure AWS credentials
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-2
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: [ECR 레포지토리 이름]
IMAGE_TAG: latest
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
- name: Get current time
uses: 1466587594/get-current-time@v2
id: current-time
with:
format: YYYYMMDD_HH-mm-ss
utcOffset: "+09:00"
- name: Generate deployment package
run: |
mkdir -p deploy
cp Dockerrun.aws.json deploy/Dockerrun.aws.json
cd deploy && zip -r deploy.zip .
- name: Beanstalk Deploy
uses: einaregilsson/beanstalk-deploy@v14
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: [EB 어플리케이션 이름]
environment_name: [EB 환경 이름]
version_label: earth-docker-${{steps.current-time.outputs.formattedTime}}
region: ap-northeast-2
deployment_package: deploy/deploy.zip
wait_for_environment_recovery: 200
하나씩 보면
1. main 브랜치에 푸쉬될때 해당 쉘스크립트가 실행된다.
2. 프로그램을 빌드 한 후 aws 에 접속한다.
3. ECR 레포지토리에 도커 이미지를 생성한다.
4. 도커 이미지를 푸시한 후, 이미지를 이용하여 EB에 배포한다.
5.Dockerfile 과 Dockerrun.aws.json
Dockerfile 은 Docker 이미지를 만들기 위해서 필요한 파일이다.
yml 파일에서 순차적으로 action을 할 때, 도커 이미지를 생성할 때 Dockerfile을 이용한다.
참고(도커 이미지 만들기) : https://thalals.tistory.com/240
Dockerrun.aws.json 파일은,
- Docker 컨테이너 세트를 Elastic Beanstalk 어플리케이션으로 배포하는 방법을 설명하는 Elastic Beanstalk 고유의 JSON파일이다.
- Dockerrun.aws.json은 환경에서 각 컨테이너 인스턴스(Docker 컨테이너를 호스팅하는 Amazon EC2 인스턴스)에 배포할 컨테이너 및 탑재할 컨테이너의 호스트 인스턴스에서 생성할 데이터 볼륨을 설명합니다.
Dockerrun.aws.json
{
"AWSEBDockerrunVersion": "1",
"Image": {
"Name": "Docker image url - ecr 레포지토리",
"Update": "true"
},
"Ports": [ { "ContainerPort" : 8080} ]
}
이러면 준비는 끝이다, 이제 git main branch에 푸시하면 배포끝!
참고
workflow란 : https://zzsza.github.io/development/2020/06/06/github-action/