[서버 구축] Jenkins Pipeline, Github Webhook, AWS EC2, Docker를 활용한 CI/CD 구축 및 서버 호스팅

이준영·2023년 7월 19일

Infra.

목록 보기
1/2
post-thumbnail

1. AWS EC2

1-1. 인스턴스 시작

AWS > EC2 > 인스턴스 > 인스턴스 시작

  • 이름 입력

  • 애플리케이션 및 OS 이미지 선택

  • 키 페어 선택

  • 새 키 페어 생성

  • 네트워크 설정(보안그룹)
    보안 그룹 생성 또는 기존 보안 그룹 선택 하면 된다.

  • 스토리지 구성
    프리티어는 30GB가 최대

  • 인스턴스 시작
    인스턴스 개수 입력 후 인스턴스 시작

1-2. 탄력적 IP 할당

EC2 > 네트워크 및 보안 > 탄력적 IP

탄력적 IP 주소 할당 > 탄력적 IP 주소 연결 > 인스턴스, 프라이빗 IP 주소 선택 후 연결


1-3. SSH Client Tool(Termius)로 EC2 인스턴스 접속

  • 설치 후 회원가입/로그인
    https://termius.com/free-ssh-client-for-mac-os

  • NEW HOST 클릭

    Label : 인스턴스 이름 입력  
    Address : 인스턴스 퍼블릭 IPv4 주소 입력
  • Set an Identity 클릭

  • NEW IDENTITY 클릭

  • 로그인 정보 입력

    Username : ec2-user(EC2 인스턴스 기본 계정)  
    Password : Keys 클릭 후 키 페어 선택
  • NEW KEY 클릭

  • Import from key file 클릭 후 키 페어 pem 파일 등록

  • 상단 Save 클릭 후 완료

Termius 설치 참고 링크 : https://code00.tistory.com/146

1-4. SWAP 메모리 설정

프리티어에서 메모리가 1GB 밖에 되지 않아서 답답함을 느끼다 찾은 해결방법이다.

  • swap 메모리 할당
    128씩 16개의 공간을 만듬 = 2GB 정도 차지
  • sudo dd if=/dev/zero of=/swapfile bs=128M count=16
  • 스왑 파일에 대한 읽기 및 쓰기 권한 업데이트
  • sudo chmod 600 /swapfile
  • Linux 스왑 영역 설정
  • sudo mkswap /swapfile
  • 스왑 공간에 스왑 파일 추가하여 즉시 사용할 수 있도록 설정
  • sudo swapon /swapfile
  • /etc/fstab 파일을 편집하여 부팅 시 스왑 파일을 활성화
  • sudo vi /etc/fstab
  • 파일 끝에 다음 내용 추가
  • /swapfile swap swap defaults 0 0

참고 : https://sundries-in-myidea.tistory.com/102

2. Docker

설치

sudo yum update -y
sudo yum install -y docker
sudo service docker start

3. Jenkins

설치

  • Jenkins 이미지를 다운 받고 Jenkins 컨테이너를 실행 한다.
  • docker pull jenkins/jenkins:lts docker run -d --name jenkins -p 8080:8080 jenkins/jenkins:lts
  • 만약 프로젝트 jdk 버전이 17이라면 기본 jdk 버전이 11이기 때문에 설치 시 lts가 아닌 jdk17로 입력 해줘야 한다.
  • docker run -d --name jenkins -p 8080:8080 jenkins/jenkins:jdk17
  • Jenkins 컨테이너 ID 확인
  • docker ps
  • Jenkins 컨테이너 진입(root)
docker exec -it --user root [CONTAINER ID] /bin/bash
  • Jenkins 컨테이너 재진입

  • docker restart [CONTAINER ID]

  • http://<EC2 인스턴스 IP 주소>:8080 접속

  • Jenkins 초기 패스워트 확인 후 복사, 붙여넣기

  • cat /var/jenkins_home/secrets/initialAdminPassword

  • 추천 플러그인 설치(Install suggested plugins)

  • 설치 완료 후 Admin 정보 입력 후 완료

Docker, Jenkins 설치 참고 링크 :
https://code00.tistory.com/146
https://velog.io/@wijoonwu/AWS-Jenkins-%EC%9E%90%EB%8F%99-%EB%B0%B0%ED%8F%AC

(사전작업) Jenkins Credential 세팅

  • Dashboard > Jenkins관리 > System > Github 탭 으로 이동

  • Add GitHub Server 클릭

  • Name 입력 후 Credentials에서 Add 클릭

  • Kind 항목에서 Secret text 선택 후 Secret, ID 입력

    Secret : Github 토큰 입력  
    ID : Credential 이름 설정
  • Credential 선택 후 test connection 클릭
    아래와 같이 나오면 성공

  • Credentials Add 다시 한번 클릭

  • Kind 항목에서 Username with password 선택 후 Username, Password, ID 입력

    Username : Github 사용자 이름 입력  
    Password : Github 토큰 입력  
    ID : Credential 이름 설정

파이프라인 생성

  • Dashboard에서 새로운 Item 클릭

  • Item name 입력 및 Pipeline 선택 후 OK

  • Pipeline 작성
    Pipeline Syntax를 활용하여 작성
    Script 작성 란 우측 상단 Hello World 선택하여 기본 틀 생성 후 stages안에 각 stage를 작성

  • git Clone
    github url과 branch명으로 프로젝트를 클론

  • stage('git Clone') { steps { git branch: 'develop', url: 'https://github.com/CommaProject/Comma-Back-end' echo 'Clone Success' } }

  • build & test
    클론 해온 프로젝트에서 Gradle로 bootJar 빌드 및 테스트 실행

  • stage('Build & Test') { steps { sh ''' chmod +x gradlew ./gradlew clean test bootJar ''' echo 'Build and Test Success!' } }

  • 테스트 통과 및 빌드 완료 된 jar파일을 ssh를 이용하여 서버로 전달

  • 사전작업
    plugin 설치

    Publish over ssh 설정  

    ssh server 정보 입력  

    1번 : syntax에서 참조할 수 있는 이름  
    2번 : 빌드된 파일을 전송할 서버의 private ip  
    3번 : username(ubuntu = ubuntu, linux = ec2-user 가 default)  
    4번 : 파일이 도착할 베이스 디렉토리를 적어줍니다.  
    모두 입력 후 Test Configuration으로 확인
  • publish on ssh

stage('publish on ssh') {
    steps{
        sshPublisher(
            publishers: [
                sshPublisherDesc(
                    configName: 'Comma-Develop', 
                    transfers: [
                        sshTransfer(
                            cleanRemote: false, 
                            excludes: '', 
                            execCommand: 'sh /home/ec2-user/deploy/script/init_server.sh', 
                            execTimeout: 120000, 
                            flatten: false, 
                            makeEmptyDirs: false, 
                            noDefaultExcludes: false, 
                            patternSeparator: '[, ]+', 
                            remoteDirectory: '/', 
                            remoteDirectorySDF: false, 
                            removePrefix: '', 
                            sourceFiles: 'build/libs/*.jar'
                            )
                    ], 
                    usePromotionTimestamp: false, 
                    useWorkspaceInPromotion: false, 
                    verbose: true
                    )
                ]
            )
        }
    }
}
  • init_server.sh

    CURRENT_PID=$(ps -ef | grep java | grep [프로젝트명] | grep -v nohup | awk '{print $2}')
    if [ -z ${CURRENT_PID} ] ; then
          echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
    else
          echo "> 실행중인 어플리케이션 : $CURRENT_PID"
          sudo kill -9 $CURRENT_PID
          sleep 10
    fi
    echo "> 배포 작업 시작"

sudo nohup java -jar -Dspring.profiles.active=dev -Dserver.port=8080
/home/ec2-user/deploy/build/libs/[jar파일명] > /dev/null 2>&1 &


- 여기까지 작성 완료 후 지금 빌드 실행 시 성공하면 완료

- 마지막 줄에 /dev/null 2>&1
원격 shell 실행 시 job이 끝나지 않아 Jenkins에서 unstable이 뜸
위 문장 추가해서 해결

- (23.07.12 수정) init_server.sh jar 파일 실시간 로그 저장하도록 명령어 변경

sudo nohup java -jar -Dspring.profiles.active=dev -Dserver.port=8080
/home/ec2-user/deploy/build/libs/comma-0.0.1-SNAPSHOT.jar
--logging.file.path=/home/ec2-user/ --logging.level.org.hibernate.SQL=DEBUG

/home/ec2-user/deploy.log 2>/home/ec2-user/deploy_err.log &

```

Jenkins 파이프라인 생성 참고 링크 : https://sihyung92.oopy.io/e5300d92-1a4e-40f4-b927-a93b2bbb17d2
Jenkins unstable 현상 참고 링크 : https://ktaes.tistory.com/100

4. 빌드 자동화

  • 위에서 만든 파이프라인을 Github Webhook으로 자동화할 수 있음

  • Jenkins 관리 > Plugins 에서 Generic Webhook Trigger 플러그인 설치

  • 위에서 만든 파이프라인 구성에서 Build Triggers 탭으로 이동

  • Generic Webhook Trigger를 선택 후 Post content parameters를 추가

  • 아래와 같이 입력



  • Github 레포지토리 > Settings > Webhooks 로 이동

  • 아래와 같이 입력 및 선택


  • 이후 푸시 혹은 PR 했을 때 recent deliveries탭에서 성공 시 완료

Github Webhook 설정 참고 링크 : https://sihyung92.oopy.io/e5300d92-1a4e-40f4-b927-a93b2bbb17d2

  • webhook 설정 후 다음과 같은 에러 발생 시 아래 링크에서 hooks에 있는 주소를 EC2 인스턴스 인바운드 보안 규칙에 추가해준다.

To do

docker-compose 활용해서 docker 컨테이너로 db랑 spring 연결 및 배포하기

profile
환영합니다!

2개의 댓글

comment-user-thumbnail
2023년 7월 19일

뛰어난 글이네요, 감사합니다.

1개의 답글