개요

백엔드 개발 시 main 브랜치 push 에 따라 자동 배포를 통해 개발 서버를 유지하고자 한다. 이를 위해 이전 포스팅에서는 Github action 와 AWS 의 S3, CodeDeploy, EC2 를 사용해서 배포하였다.

이번에는 Docker 를 사용해 DockerHub 와 EC2 만으로 간단하게 배포해보자.

image

전체적인 구조는 위와 같다.

  1. Github 에 push 시에 Github Action 이 동작한다.
  2. Github Action 을 통해 Docker 이미지가 생성되고 Docker Hub 에 저장된다.
  3. Github Action 에서 ssh 를 통해 EC2 에 직접 접근해 Docker Hub 의 이미지를 가져와 실행시킨다.

해당 프로세스를 통해 Github push 를 통해 개발 서버를 배포할 수 있다!

코드 작성

Dockerfile

FROM amazoncorretto:17

WORKDIR /usr/app

COPY ./build/libs/demo-0.0.1-SNAPSHOT.jar /usr/app/app.jar

CMD ["java", "-jar", "app.jar"]

build 된 jar 파일을 통해 Docker 이미지를 만드는 Dockerfile 이다.

workflows

name: Java CI with Gradle

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

jobs:
  build:

    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: 'corretto'

    - name: gradlew permmision
      run: chmod +x ./gradlew
    # 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
    - name: Setup Gradle
      uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0

    - name: Build with Gradle Wrapper
      run: ./gradlew clean build -x test

    - name: Docker build
      run: |
        docker login -u $ -p $
        docker build -t app .
        docker tag app $/cicd_docker
        docker push $/cicd_docker

    - name: Deploy
      uses: appleboy/ssh-action@master
      with:
        host: $
        username: $
        key: $
        script: |
          docker pull $/cicd_docker
          docker stop $(docker ps -a -q)
          docker rm $(docker ps -a -q)
          docker run -d --log-driver=syslog -p 8080:8080 $/cicd_docker
          docker rm $(docker ps --filter 'status=exited' -a -q)
          docker image prune -a -f

Github Action 에서 dockerfile 을 빌드하고 ssh로 EC2 에서 해당 이미지를 실행시켜야한다.

이를 위해 secrets 에 아래 요소를 넣어야한다.

  • DOCKER_USERNAME : Docker Hub 의 아이디
  • DOCKER_PASSWORD : Docker Hub 에 로그인 할 수 있는 비밀번호
  • SSH_HOST : EC2 의 Host
  • SSH_USERNAME : EC2 의 Username
  • SSH_KEY : EC2 의 .pem key

주의 사항

SSH 를 통해 접속하기 때문에 port 를 열어놓아야한다. Github Action 의 IP 주소를 알아내 배포 시 해당 IP 를 ssh 루트에 추가해 배포하고 다시 삭제하는 방법도 사용 가능하지만 여기에서는 모두 열어두었다.

image

Github Action 에서 Inbound 규칙 추가하기

# 1. Github Action IP 주소
- name: Get Github Actions IP
        id: github_action_ip 
        uses: haythem/public-ip@v1.2 

# 2. AWS 인증과정
- name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with: 
          aws-access-key-id: $
          aws-secret-access-key: $
          aws-region: ap-northeast-2

# 3. IP 주소 보안 그룹에 추가
- name: Add Github Actions IP to Security group
        run: |
          aws ec2 authorize-security-group-ingress --group-id $ --protocol tcp --port 22 --cidr $/32

...

# 4. IP 보안 그룹에서 제거
- name: Remove Github Actions IP From Security Group
  run: |
    aws ec2 revoke-security-group-ingress --group-id $ --protocol tcp --port 22 --cidr $/32

4 가지 단계를 걸쳐 해당 Github Action 이 실행되는 IP 주소를 일시적으로 ssh 접속 허용이 가능하다.

결과

image image

결론적으로 더 간단한 프로세스로 CI/CD 를 구성할 수 있다.

Github Code

참고

AWS + Github Action + Docker로 spring 서버 자동배포하기

업데이트:

댓글남기기