회사 서비스 백엔드를 개발하던 도중 서버에 자동 배포해야할 상황이 생겨, CI/CD 하는 법을 남길려고 합니다.
서버 비용을 절약하고자 AWS EC2를 ARM64 계열을 활용하는데, 그 과정에서 기존 x64/AMD64 계열 CPU로는 정상적으로 실행이 되지 않는 경우가 있어 이를 해결하는 방법을 공유하고자 합니다. 물론 아래 과정을 통해 기존 CPU를 가진 EC2 인스턴스에서도 정상적으로 실행할 수 있습니다! 또한 꼭 AWS가 아니라 자체 서버나 Azure 같은 타 클라우드 서비스여도 상관은 없습니다.
설명시에는 도커와 CI/CD, AWS에 대한 개념 설명을 생략하고 진행하겠습니다. 본 개념에 대해 잘 알지 못하신다면 다른 포스팅을 참고하셔서 개념 알아가면서 보시면 될 것 같습니다.
1. 먼저 Github에서 계정 접속을 위한 Access Token을 발급합니다.
오른쪽 위에 있는 메뉴 버튼을 클릭 후 Settings으로 들어가줍니다.
설정 탭에 맨 밑에 존재하는 'Developer settings'을 클릭한 후 'Personal access tokens (classic)'에 들어가줍니다.
들어간 후 'Generate new token' 버튼을 눌러줍니다.
이름은 'ghcr_token'으로 설정해주시고, 유효기간은 없음으로 설정해주세요. 토큰의 만료를 막기 위함입니다.
권한은 'repo', 'workflow', 'write:packages', 'delete:packages' 총 4가지의 권한을 추가 후 토큰을 생성해주시면 됩니다.
생성된 토큰 홈페이지에 'ghp_'로 시작하는 문자열로 표시될텐데, 복사한 후 다른 곳에 붙여넣어 토큰을 저장해주시기 바랍니다. 토큰은 처음 생성시 말고는 홈페이지에서 더이상 확인할 수 없으니까요.
다음으로 Repository 설정에서 'Secrets and variables' -> 'Actions'을 들어가주세요.
들어간 후에 'New repository secret' 버튼을 클릭해주세요. 버튼을 눌러 Secret 등록창에 들어갔다면 이름에는 'GHCR_TOKEN'을, 내용에는 아까 생성한 토큰을 붙여넣어주신 후 등록을 완료해주세요.
2. AWS EC2 Instance를 생성하고 GIthub Action에 Runner로 서버를 등록한다.
Github Action에 Runner라는 것으로 저희가 생성한 EC2 Instance를 등록하면 Github Action 실행시 Runner로 등록된 서버에 접속하여 명령어를 실행할 수 있습니다. 저희는 Action내에서 EC2를 접속하여 도커 컨테이너를 열어야 하기 때문에 등록을 진행해줍니다.
먼저 AWS에 EC2 Instance를 생성해줍니다. 위에서 말씀드린 것처럼 AWS가 아니라 자체 서버나 Azure 같은 타 클라우드 서비스여도 상관은 없습니다. 생성이 되었다면 서버에 SSH로 접속을 진행합니다. 본 서버에는 도커가 설치되어있다고 가정합니다, 만약 설치가 안되어 있다면 아래 명령어를 입력해 도커를 설치해주세요.
(ARM 계열 Amazon Linux 기준, 타 운영체제의 경우 각자 서버에 맞추어 도커 설치 명령어를 입력하세요.)
sudo yum update
sudo yum install docker
그 다음 Repository에 설정으로 들어가 Actions -> Runners 설정으로 들어가줍니다.
들어간 후 'New self-hosted runner' 버튼을 눌러줍니다.
서버에 맞는 운영체제와 Architecture를 선택해 준 후 나오는 명령어를 순서대로 SSH로 접속한 서버에 실행시키면 Runner가 등록이 됩니다. 다만 ARM 계열의 CPU를 사용하고 계시다면, 위 사진에 나와있는 명령어를 사용하기 전 아래에 적혀있는 명령어를 먼저 실행하여야 정상적으로 작동합니다. (2023.01.19기준)
cd
wget https://github.com/unicode-org/icu/releases/download/release-68-1/icu4c-68_1-src.tgz
mkdir icubuild
cd icubuild
tar -xzf ../icu4c-68_1-src.tgz
cd icu/source
sudo yum install gcc-c++
mkdir ~/libicu
./configure --prefix=/home/ec2-user/libicu
make
make install
cd
rm icu4c-68_1-src.tgz
rm -rf icubuild
위 코드를 실행하셨으면, .bash_profile 파일에 아래 두줄을 추가시켜 저장한 후, 로그아웃 후 재 로그인을 진행해주면 ARM계열에서도 Github Action의 Runner을 정상적으로 등록할 수 있습니다.
LD_LIBRARY_PATH=$HOME/libicu/lib
export LD_LIBRARY_PATH
Runner 등록 명령어 중 ./config.sh~라고 시작하는 명령어가 있을텐데, 본 명령어를 실행하면 서버에 대한 세팅을 진행하게 되며 그 과정에서 여러 정보를 요구합니다. 총 4가지 질문이 나오는데, 대응방법은 아래와 같습니다.
- Enter the name of the runner group to add this runner to : Enter키 눌러 넘어가기
- Enter the name of runner : Enter키 눌러 넘어가기
- Enter any additional label : (본인이 지정할 서버의 태그 이름 작성)
- Enter name of work folder : Enter키 눌러 넘어가기
홈페이지에 나오는 마지막 ./run.sh 코드는 아래 명령어를 대신 쳐주시면 됩니다.
nohup ./run.sh &
최종적으로 실행이 된다면 서버 등록이 완료된 것이며, Github의 Runner 목록에서 서버가 등록된 것을 확인할 수 있습니다.
또한 서버상에서 실행되고 있는 Runner의 로그는 아래 명령어를 통해 확인할 수 있습니다.
tail -f nohup.out
3. Github Repository에 Github Action 설정 파일을 추가한다.
이제 Repository에 Github Action 설정 파일 추가를 진행합니다. 파일의 경로는 .github/workflows/docker_deploy.yml 입니다.
아래 내용을 추가해주시면 되며, 코드 중간중간 Repository 이름, 서버 태그 같은 부분은 현재 세팅하고자 하는 값으로 바꾸어 설정해주시면 됩니다.
설정 파일 중간에 platforms: linux/amd64,linux/arm64 설정이 있는데, 이는 ARM 계열의 CPU에서도 도커 이미지가 정상적으로 동작하기 위해 필요한 설정으로 AMD계열, 즉 일반 CPU를 사용하신다면 본 설정을 지우시는 것이 CI/CD 속도에 더 유리하니 일반 CPU를 사용하고 계신다면 본 설정 라인을 지워주세요.
# github repository Actions 페이지에 나타낼 이름
name: Docker Container CI/CD
# 트리거를 수행할 브랜치를 지정합니다.
on:
push:
branches: [ main ]
# 환경설정
env:
DOCKER_IMAGE: ghcr.io/${{ github.actor }}/<Repository 이름>
VERSION: ${{ github.sha }}
NAME: harang-backend
jobs:
# 빌드 Job
build:
name: Build
runs-on: ubuntu-latest
steps:
# github repository에서 checkout
- uses: actions/checkout@v2
# docker build 수행
- name: Set up docker buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Cache docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ env.VERSION }}
restore-keys: |
${{ runner.os }}-buildx-
# GitHub 컨테이너 레지스트리에 로그인 후 빌드 & 푸시
- name: Login to ghcr
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
push: true
tags: ${{ env.DOCKER_IMAGE }}:latest
platforms: linux/amd64,linux/arm64 #ARM, AMD Architecture 동시 빌드 진행
# 배포 Job
deploy:
needs: build # build 후에 실행되도록 정의
name: Deploy
runs-on: [ self-hosted, <서버 태그 이름> ] # AWS ./configure에서 사용할 label명
steps:
- name: Login to ghcr
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_TOKEN }}
# 3000 -> 80 포트로 수행하도록 지정
- name: Docker run
run: |
docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest
docker run -d -p 5001:5001 --name <Repository 이름> --restart always ${{ env.DOCKER_IMAGE }}:latest
이렇게 설정을 진행하신다면 자동적으로 CI/CD가 진행되게 되며, 성공적으로 도커 컨테이너가 자동 빌드 후 배포되게 됩니다!
Reference
'프로그래밍 > 클라우드' 카테고리의 다른 글
Docker Windows Container CMD/ENTRYPOINT 사용 시 뜨는 오류해결 (0) | 2022.04.17 |
---|---|
AI-900: Microsoft Azure AI Fundamentals 합격 후기 (0) | 2022.02.05 |
AZ-900: Microsoft Azure Fundamentals 자격증 시험 등록 & 준비 방법 및 합격 후기 (2) | 2022.01.29 |