본문 바로가기

연재작/DevOps

EC2 Tomcat Server pipeline 구축 + S3 정적 웹서버와 연동

 

정적 웹페이지를 S3에 구축했지만, 여전히 페이지가 제대로 작동하지는 않는다.

아직 API 요청에 응답해주는 서버를 구축하지 않았기 때문이다.

 

이번에는 EC2에 docker를 이용한 tomcat server를 만들고자 한다.

일단은 public에 서버를 형성하고, 나중에 security 기능을 추가하는 것으로 생각중이다.

 

우선 기본 VPC 세팅은 지난번 글 

https://namucy.tistory.com/47

 

AWS EC2 Private Instance 구축 (2) VPC, 서브넷, IGW, 라우터 테이블

지난 번에 그려놨던 아키텍쳐를 토대로 VPC 및 서버(인스턴스) 설정의 절차를 소개하겠다. 1. Root 사용자 vs IAM 사용자일단 AWS "콘솔에 로그인" 을 누르면 IAM 사용자 로그인창이 먼저 뜨지만, 아

namucy.tistory.com

를 참고하면 좋을 듯 하다.

 

1.

이제, public subnet에 EC2 인스턴스 하나를 생성할 것이다.

프리티어로 사용중이기에 Amazon Linux의 t2.micro를 사용한 EC2를 생성하고, public IP 자동 할당 활성화

Security Group(보안 그룹)의 인바운드 규칙에

TCP 0.0.0.0 / 0의 8080 포트와 SSH 0.0.0.0 / 0의 22번 포트를 허용하는 인스턴스를 생성한다.

전자는 외부의 어떤 ip 에서든 8080 포트의 TCP 프로토콜로 요청할 경우를 받는 것이고

후자는 외부의 어떤 ip 에서든 22번 포트의 SSH 프로토콜로 요청할 경우를 받는 것이다.

 

2. 

그리고 ec2에 접속해 다음의 명령어들을 입력한다

sudo yum upgrade -y && yum update -y  // yum 업데이트

sudo yum install docker -y // docker 설치

sudo service docker start // docker 실행

 

3.

한편, github action 호스트가 SSH로 접속할 때 사용할 username과 password를 입력해주어야 한다.

username은 ec2를 연결할 때 아래에 생성되는 것이 username이다.

다른 설정을 하지 않았다면 ec2-user 가 username이 될 것이다.

password는 다음과 같이 설정한다. ec2 콘솔에 연결 한 후

 

sudo passwd ec2-user // ec2-user에 비밀번호를 설정함. 비밀번호가 안보이더라도 입력된 것이니 주의

 

그리고 ssh의 설정을 id, pw 기반으로 접근할 수 있도록 설정해야 한다.

sudo vim /etc/ssh/sshd_config

 

들어가서 

":" ➡️ set nu 또는 set number 를 입력하면 줄 번호가 표시된다.

65번 줄에 가서 "i" ➡️ PasswordAuthentication yes 로 바꾼다.

ESC ➡️ ":wq" 입력 

sudo systemctl restart sshd

를 통해 sshd의 service를 재시작해 설정 변경을 반영한다.

 

4. IAM 의 ec2FullAccess 권한을 사진 사용자의 액세스 키와 값을 형성.

추가적으로 docker hub의 push와 pull 에 사용할 dockerhub id와 access key 값을 설정한다.

 

이를 설정 한 후 아래처럼 Dockerfile을 설정하고

FROM amazoncorretto:17-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

 

아래처럼 .github/workflows/action.yml 을 설정한다.

name: Spring Boot CI/CD Pipeline

on:
  push:
    branches: [ 'branch-name' ]

jobs:
  Spring_Boot_CI_CD_Pipeline:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'corretto'
          java-version: '17'

      - name: Run chmod to make gradlew executable
        run: chmod +x ./gradlew

      - name: Build Spring Boot Project with Gradle Wrapper
        run: ./gradlew clean build

      - name: Build Docker Image
        run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/temp-spring-boot .

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: docker Hub push
        run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/temp-spring-boot

      - name: get Runner's Public IP
        id: ip
        uses: haythem/public-ip@v1.3

      - name: Configure AWS IAM credentials in repository secrets
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

      - 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

      - name: Executing remote ssh commands using password with AWS EC2
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          password: ${{ secrets.EC2_PASSWORD }}
          port: ${{ secrets.EC2_SSH_PORT }}
          timeout: 60s
          script: |
            sudo docker stop temp-spring-boot \
            && sudo docker rm temp-spring-boot \
            && sudo docker rmi ${{ secrets.DOCKERHUB_USERNAME }}/temp-spring-boot \
            || true
            sudo docker run -it -d -p 8080:8080 \
            --name temp-spring-boot ${{ secrets.DOCKERHUB_USERNAME }}/temp-spring-boot

      - 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

 

 

5. 이를 통해서 ec2 instance 위에 tomcat 서버를 형성 했다면, 서버를 열어놓은 상태에서

ec2의 public ip를 통해 S3에 접근하도록 api의 URL 을 수정한 뒤 S3를 다시 빌드 한 후,

S3를 업로드 하면 된다.

 

이때, CORS 이슈가 발생할 수 있으니 Spring Boot 에 WebMvcConfig에 CORS설정을 추가해줄 것을 권장한다.