이전에는 수동으로 배포하는 과정을 한번 해봤었는데 더욱 편하게 개발하기 위해 자동으로 배포하는 방법을 해보자.
1. 환경변수 설정
깃허브의 해당 프로젝트 레포지토리에 들어가서
Settings -> Secrets and variables -> actinos -> New repository secret 에서
환경 변수를 설정해준다.
일단은 DockerHub의 username과 password를 등록하도록 한다.
2. Actions -> yml 생성
Java with Gradle을 실행하게 되면 yml을 편집할 수 있는 창이 나오는데
아래의 내용들로 수정해준다.
name: Java CI with Gradle
#main 브랜치가 수정될 될 때 해당 actions을 실행하겠다.
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build-docker-image:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
# Spring boot 애플리케이션 빌드
- name: Setup Gradle
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
with:
arguments: clean bootJar
# Docker 이미지 빌드
- name: docker image build
run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/feed-dev .
# Docker 로그인
- name: docker login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# Docker Hub 이미지 푸시
- name: docker Hub push
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/feed-dev
steps의 단계들은 이전에 도커를 통해 수동으로 배포했을 때의 내용을 자동으로 하기 위해 추가 한다고 생각하면 된다.
여기까지 하면 DockerHub에 이미지를 Push한 상태이고, Ec2에 들어가서 해당 이미지를 실행하기만 하면 배포 완료다.
우리는 여기서 Docker를 실행하는 것까지 자동으로 해야한다.
3. 배포 자동화하기
배포를 자동화하는 방법은 여러가지가 있지만 가장 간단하다고 생각하는 방법으로 진행해보려고 한다.
환경변수를 더 추가해줘야 하는데 여기서 추가해줘야 하는 부분은
이렇게 4가지이다.
각각 EC2를 연결하기 위해 추가적으로 만들어줘야한다.
여기서 PASSWORD는 ssh를 패스워드로 접속하기 위해 하는 부분이라 없어도 되는 부분인데 하는 방법만 추가해놓도록 한다.
EC2 ubuntu password로 접속가능하게 하기
1. 접속후 아래 명령어로 패스워드 생성하기 sudo passwd ubuntu 2. sshd_config 파일 열기 sudo vi /etc/ssh/sshd_config 3. PasswordAuthentication no 항목을 찾아서 yes로 변경하기 4. ssh 재시작 sudo service sshd restart 5. 아
nyagm.tistory.com
EC2_PASSWORD : ssh를 패스워드로 접속하는 경우만 사용 여기선 사용 x 없어도 됨
EC2_PRIVATE_KEY : .pem 파일이 있는 폴더로 가서
cat xxx.pem
을 하게 되면 나오는 key를 넣으면 된다. 처음엔 EC2에 있는 id_rsa를 사용해서 key를 설정했었는데 접속이 안되는 오류가 발생했음.
EC2_USERNAME : ubuntu의 username을 사용하면 된다. EC2에서 whoami를 입력하게 되면 나오는 이름 (기본은 ubuntu)
HOST_DEV : EC2의 퍼블릭 IPv4 DNS나 퍼블릭 IPv4 주소를 입력
여기서는 appleboy를 사용해서 CD를 하려고 한다.
https://github.com/appleboy/ssh-action#setting-up-ssh-key
GitHub - appleboy/ssh-action: GitHub Actions for executing remote ssh commands.
GitHub Actions for executing remote ssh commands. Contribute to appleboy/ssh-action development by creating an account on GitHub.
github.com
PASSWORD를 사용해서 ssh를 연결하는 방법과 KEY를 사용하는 방법들이 있는데 여기서는 KEY를 이용했다.
위의 gradle.yml 파일의 아래 부분에
# 이미지 실행
run-docker-image-on-ec2:
needs: build-docker-image
runs-on: ubuntu-latest
steps:
## deploy to develop
- name: Deploy to dev
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST_DEV }} # EC2 퍼블릭 IPv4 DNS
username: ${{ secrets.EC2_USERNAME }} # ubuntu
#password: ${{ secrets.EC2_PASSWORD }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
port: 22
envs: GITHUB_SHA
script: |
sudo docker ps
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/feed-dev
sudo docker stop $(sudo docker ps -q) 2>/dev/null || true
sudo docker run -d -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/feed-dev
sudo docker image prune -f
이렇게 추가를 해주고 main 브랜치를 수정하게 되면 배포가 자동으로 성공하게 된다.
테스트를 하기 위해 테스트 컨트롤러를 하나 만들어서 push했고 main 브랜치로 merge했다.
infra/1 브랜치에서 main브랜츠로 머지를 했을 때 자동으로 배포가 되었고
문제없이 CD가 되는 것을 확인했다.
4.후기
간단하게 CI/CD를 적용해봤는데 생각보다 어려워서 시간이 많이 걸렸다. 결국 CI/CD를 하는 목적에 테스트를 잘 하기 위함도 있기 때문에 이번 프로젝트에서는 꼭 테스트를 적용해 볼 예정이다.
Github Actions + Docker + EC2로 CI/CD를 해봤는데 여기서 문제점은 배포가 되고 Docker 이미지가 껐다 켜지는 동안 사이트가 죽는 경우가 발생한다. 이슈를 해결하기 위해서 다음에는 nginx를 사용해서 Blue-Green 무중단 배포를 한번 적용해 볼 예정이다.