[Docker] GitHub Action을 이용한 Amazon EC2 Spring 프로젝트 자동 배포

Kim Dong Hyun·2023년 7월 26일
0

Server

목록 보기
4/5
post-thumbnail


Amazon EC2 Linux환경에서 진행했다.






EC2 Docker 설치


sudo yum update -y

시작하기 전에 yum 패키지를 모두 최신 버전으로 업데이트 해주었다.



sudo yum install docker -y

yum을 이용해서 docker를 설치했다.

  • Docker 버전 확인
docker -v

  • Docker 시작
sudo service docker start

  • Docker 그룹에 ec2-user 를 넣어서 관리자 권한으로 실행할 수 있게 해준다.
sudo usermod -aG docker ec2-user

  • 최신 버전의 Docker Compose 설치
sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose

이후, 인스턴스 재 시작 후 Docker 명령어를 실행해보자.

docker run hello-world







AWS IAM 설정

AWS IAM 은 AWS의 기능들을 원격으로 사용할 권한이 있는 사용자를 관리하는 서비스이다.

aws에서 IAM 서비스로 들어가서 사용자로 들어간다.


사용자 추가를 눌러주자.

원하는 이름을 입력하고 다음을 누른다.

권한 설정 중에, 직접 정책 연결에서 EC2FullAcess를 검색하고 추가해준다.

그대로 사용자 생성을 눌러준다.


사용자가 생성 되었다면, 눌러서 세부 설정을 해주자.


아래에 보안 자격 증명 탭을 누르면, 엑세스 키 만들기 버튼이 있다.


AWS 컴퓨팅 서비스에서 실행되는 어플리케이션을 선택하고 다음을 누른다.

원하는 태그를 입력하면, 엑세스 키가 발급된다.

엑세스 키를 어느 곳에다가 복사해 두거나, csv파일을 받아놔서 소중히 잘 보관해두자.
다른 곳에(특히 github)에 절대로 유출되면 안된다!!







EC2 접근 설정

원래는 ssh를 이용해서 접근하는 방법을 사용할 수 있겠지만,
EC2 내에서 ID와 Password를 이용해서 접근하는 방법을 이용해 보겠다.


whoami


보통은 ec2의 username은 ec2-user이다. 명령어를 이용해서 미리 확인해 보자.




sudo passwd {username}

sudo passwd ec2-user

위 명령어를 통해 새로운 비밀번호를 설정할 수 있다. 원하는 비밀번호로 설정해주자.




이제, 비밀번호를 통해 접근하는 것을 허용해주자.

sudo vi /etc/ssh/sshd_config


편집기를 열어서 PasswordAuthentication 을 yes로 바꿔주자.
/Password 를 이용하면 쉽게 찾을 수 있다.

sudo systemctl restart sshd 

설정하고 나면 sshd를 재시작 해준다.




이제, ec2를 나와서(ctrl+D) 비밀번호로 접근이 되는지 확인해보자.

sudo ssh [username]@[ec2 인스턴스 ip (퍼블릭 IPv4 DNS)]

sudo ssh ec2-user@ip








Docker Token 설정


Docker Hub에서 내 계정 설정에 들어간다.

Security부분에 New Access Token을 눌러서 토큰을 만들어 준다.


해당하는 이 토큰을 소중히 잘 갖고있자.








GitHub Action Secret 설정

위 Action 스크립트에서 사용했던 여러 키들을 Secret으로 관리할 수 있다.
Settings -> Secrets and Variables -> Actions에 들어와서
New repository secret을 눌러주자.


여기서 여러 키들을 생성할 수 있는데, 다음 키들을 생성해 주자.

  • DOCKERHUB_USERNAME : Docker Hub 닉네임 입력
  • DOCKERHUB_TOKEN : 방금 받았던 Docker Hub 토큰 입력
  • AWS_ACCESS_KEY_ID : 위 AWS IAM에서 발급받은 ACESS KEY를 입력
  • AWS_SECRET_ACCESS_KEY : IAM에서 발급 받은 SECRET KEY를 입력
  • AWS_SG_ID : EC2 보안그룹ID
  • EC2_HOST : EC2의 퍼블릭 IPv4 주소.
  • EC2_PASSWORD : EC2에 접근/연결 설정해두었던 패스워드.
  • EC2_SSH_PORT : SSH로 접근할 port. (22)
  • EC2_USERNAME : EC2의 계정명. (ec2-user)

여기서 보안그룹ID는, 해당 인스턴스의 보안그룹에 들어가서 확인할 수 있다.

모든 KEY들을 완성했다.
이 KEY들은 GitHub Action의 스크립트 내에 알맞게 들어가서 실행 될 것이다.








프로젝트 Docker 설정

Spring 프로젝트 내에 Dockerfile을 만들어주자. 파일 이름이 다르면 안됨!!

아래 내용을 작성해준다.

  • maven
# Maven
FROM openjdk:11-jdk

# Jar 파일의 위치
ARG JAR_FILE=target/*.jar

# app.jar는 경우에 따라 이름 변경
COPY ${JAR_FILE} app.jar

# 생략 가능 - 해당 컨테이너는 8080 port 를 사용한다는 의미.
EXPOSE 8080

# docker run 시 실행할 필수 명령어
ENTRYPOINT ["java", "-jar", "/app.jar"]

# 경우에 따라 java 옵션 사용.
# ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=docker", "/app.jar"]
  • gradle
FROM openjdk:11-jdk
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Dspring.profiles.active=docker", "-jar", "app.jar"]

gradle이라면 build.gradle에 아래 내용도 추가해준다.

jar {
	enabled = false
}




버전이 다른 내용이 있으면 알맞게 바꿔서 사용하면 된다!!

그리고

./gradlew build -x test

명령어로 빌드를 한 번 해주자.
















Docker 이미지 생성

이제, Docker에서 사용할 프로젝트 이미지를 생성해야 한다.

DockerHub의 닉네임으로 로그인할 수 있다.

docker login -u [username]

로그인에 성공하면 자동으로 비밀번호를 암호화하여 저장해둔다.







GitHub Action 설정


원하는 레포지토리 > Actions에 들어와보자.


여기서 Java with Gradle을 선택하면,


gradle.yml 스크립트를 생성할 수 있다.


아래 내용을 작성해주자.

name: Java CI with Gradle

on:
  push:
    branches: [ "main" ] #push할 경우 사용 할 branch 명 기입

jobs:
  deploy: 
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v3
      
    - name: Set up JDK 17 
      uses: actions/setup-java@v2
      with:
        java-version: '17'  #Java 버전 기임
        distribution: 'temurin'
    
    # Spring Boot Build
    - name: Spring Boot Build
      run: ./gradlew clean build -x test #test 제외 build
    
    # Docker Image Build
    - name: Docker Image Build
      run: docker build -t donghyunss/spring-docker . #image명 기입
    
    # DockerHub Login
    - name: Docker Hub Login 
      uses: docker/login-action@v2
      with: 
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}

    # Docker Hub push
    - name: docker Hub push
      run: docker push donghyunss/spring-docker
      
    # GET GitHub IP
    - name: Get GitHub IP 
      id: ip
      uses: haythem/public-ip@v1.2
      
    # Configure AWS Credentials - AWS 접근 권한 취득(IAM)
    - 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 # AWS EC2 지역명 기입
    
    # Add github ip to AWS
    - name: Add GitHub IP to AWS
      run: |
        aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
    
    # AWS EC2 Server Connect & Docker 명령어 실행 (8)
    - name: AWS EC2 Connection
      uses: appleboy/ssh-action@v0.1.6
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USERNAME }}
        password: ${{ secrets.EC2_PASSWORD }} 
        port: ${{ secrets.EC2_SSH_PORT }}
        timeout: 60s
        script: | #Docker Image명 기입, port 기입
          sudo docker stop spring-docker
          sudo docker rm spring-docker
          sudo docker run -it -d -p 8080:8080 --name spring-docker donghyunss/spring-docker
    
    # REMOVE Github IP FROM security group (9)
    - name: Remove IP FROM security group
      run: |
        aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32

https://lucas-owner.tistory.com/50 에서 빠진 부분과 몇 가지 수정을 했다.

Github AWS 연결 공식 문서 >> https://github.com/appleboy/ssh-action

중간에 프로젝트에 맞는 Java 버전, Docker Image명, 원하는 port등을 수정해서 사용하면 되겠다.

















Push 테스트

이제 깃허브에 푸시를 진행해보자.

푸시를 진행하면, Action에서 push를 감지하고 커밋 메세지 명으로 된 Action을 시작하게 된다.

그리고 Action이 모두 완료되면, 아래와 같이 성공으로 뜬다.

여기서 오류가 난다면, 안으로 들어가서 어디가 오류 났는지 찾아보고 고쳐야한다...

대부분은 스크립트 내에 설정 오류일 확률이 높다. gradle.yml 파일에 내가 넣은 설정이 맞는지 확인해보자.

만약 모든 스크립트가 성공했다면,

Docker Desktop에 이미지가 정상적으로 push됐는지 확인해보자.

1개의 댓글

comment-user-thumbnail
2023년 7월 26일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기