룸메이트 매칭 프로젝트 5주차

윤장원·2023년 7월 24일
0

5주차엔 서버 배포, 프로젝트 노션 정리, README 작성을 했다. 서버 배포 과정은 다음과 같다. 백엔드 Repository의 main 브랜치에 push가 되면 github actions를 이용해 CICD 과정을 거친다. 서버 API 이미지를 Build 및 Push하고 AWS EC2 인스턴스에 접속하여 해당 이미지를 pull 받은 다음에 docker compose를 통해서 API 서버 2개, Mysql, MongoDB, Redis, Nginx, RabbitMQ를 실행시킨다. 작성한 github actions workflow는 다음과 같다.

ci-cd.yml

name: ci-cd
on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Check Branch
        run : echo "current Branch is .. := ${GITHUB_REF#refs/heads/}"

      - name: Checkout repository 👀
        uses: actions/checkout@v2

      - name: Set up JDK 🐘
        uses: actions/setup-java@v2
        with:
          java-version: '11'
          distribution: 'adopt'

      - name: Grant execute permission for gradlew 🐘
        run: chmod +x gradlew

      - name: Gradle Caching
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Build with Gradle 🐘
        run: ./gradlew build

      - name: Build Docker img 🐋
        run: |
          docker build -t yjjjwww/banggabgo:${{github.sha}} .
          docker tag yjjjwww/banggabgo:${{github.sha}} yjjjwww/banggabgo:latest

      - name: Log in to Docker registry 🐋
        uses: docker/login-action@v1
        with:
          registry: docker.io
          username: ${{ secrets.DOCKER_USERNAME_TEST }}
          password: ${{ secrets.DOCKER_PASSWORD_TEST }}

      - name: Push Docker ✔
        run: |
          docker push yjjjwww/banggabgo:${{github.sha}}
          docker push yjjjwww/banggabgo:latest

      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ubuntu
          key: ${{ secrets.KEY }}
          script: |
            if [ -d "FAB-BE" ]; then
              rm -rf FAB-BE
            fi
            git clone https://github.com/Team-FAB/FAB-BE.git
            cd FAB-BE/banggapgo-docker/env/
            echo "${{ secrets.MYSQL_ENV }}" | base64 --decode > mysql.env
            echo "${{ secrets.API_ENV }}" | base64 --decode > api.env
            echo "${{ secrets.MONGO_ENV }}" | base64 --decode > mongo.env
            sudo chmod 666 /var/run/docker.sock
            sudo docker pull yjjjwww/banggabgo
            sudo docker compose up -d --build
            sudo docker image prune -f

프로젝트 폴더 속 banggapgo-docker 폴더는 다음과 같이 구성되어 있다.

docker compose up을 실행시키면 설정대로 API 서버, MongoDB, Mysql, Nginx, RabbitMQ, Redis가 실행이 된다. env 폴더 속 api.env, mongo.env, mysql.env는 프로젝트 정보가 담겨있기 때문에 Github Actions에서 Secrets를 통해 AWS EC2 인스턴스에서 파일을 생성하도록 해주었다.

몇 번의 시행착오 끝에 main 브랜치에 push가 되면 AWS EC2에서 docker compose up까지 되는 것을 확인했다. 하지만 Nginx에서 문제가 발생했었다. 서버 API를 두 개의 포트로 열어두고, Nginx로 로드밸런싱을 통해 서버가 부담하는 부하를 분산하도록 하려고 했다. 하지만 Postman으로 API 테스트를 했을 때 서버 API 두 개의 포트로 보내는 요청은 성공적으로 보내졌지만 80 포트로 보내서 Nginx로 로드밸런싱을 거치는 요청은 제대로 처리가 되지 않았다. 그리고 local 환경에서 이미지 업로드 할 때 파일 크기가 커도 문제가 없었지만 배포 환경에서는 1MB가 넘는 파일을 업로드 할 때 에러가 발생하는 것을 발견했다. 이 문제들을 해결하기 위해 Nginx 설정 파일을 다음과 같이 작성했다.

nginx.conf

user  www-data;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
  }
http {
    client_max_body_size 10M;

    upstream backend {
        server api1:8083;
        server api2:8084;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
        location /ws {
          proxy_pass http://backend/ws;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
        }
    }
}

해당 Nginx 설정을 AWS EC2에 적용 시킨 결과 문제를 해결할 수 있었다.

그 다음으로 프론트엔드에서도 Vercel를 통해 배포를 했고, 프론트엔드 배포 주소와 백엔드 배포 주소 연결 테스트를 진행했다. 하지만 처음에 405 에러가 발생했다. 405 에러 관련해서 검색한 결과, 프론트엔드 배포 설정에 문제가 있었다는 점을 발견하고 해당 문제를 해결하여 405 에러는 발생하지않았다. 그런데 405 에러가 나오지 않는 대신 Mixed Content 에러가 발생했다. 해당 에러는 프론트엔드는 Vercel로 배포하여 Https로 배포가 되었지만 백엔드 서버는 따로 Https 설정을 해주지 않아 발생한 문제였다. 해당 문제를 해결하기 위해 백엔드 서버도 Https 설정을 하기로 결정했고, CloudFlare를 사용하기로 했다. CloudFlare에 DNS를 등록하고 Page Rule 설정을 통해 서버 Https 설정을 할 수 있었다. 프론트엔드 주소와 CloudFlare는 서로 Https 통신을 하고, CloudFlare와 백엔드는 Http 통신을 하게 되어 문제를 해결할 수 있었다.

이번 프로젝트를 통해 AWS EC2와 Docker를 이용한 서버 배포, 그리고 Github Actions를 통한 CICD 구현까지 해볼 수 있어서 매우 좋은 경험이었다. 중간에 많은 문제들이 발생했지만 문제들을 해결하는 과정에서 배포에 대한 두려움도 없앨 수 있었고, Docker와 Nginx에 관해서도 자세히 공부할 수 있었다.

프론트엔드와 백엔드 배포까지 성공적으로 마친 후, 발표를 위한 화면을 구성하기 위해 DB에 유저 생성, 게시글 생성 작업을 했다. 결과물을 봤을 때 5주 동안 열심히 달려온 과정들도 생각이 났고, 결국 해냈구나 라는 생각이 들어 매우 뿌듯했다.

그 다음으로 포트폴리오용 노션 페이지 정리를 했다. 프로젝트 배경과 기능 설명, 시연 영상, 프로젝트 아키텍처, 기술 스택, CICD 구조, 트러블 슈팅, 팀원 소개 등을 작성했다.

프로젝트 노션 페이지 : https://lowly-balloon-a7c.notion.site/719fcec4f7e446bda2db4447912dc4fc?pvs=4

0개의 댓글