React + Nginx + github action 도커, 배포자동화 정리

horiz.d·2023년 7월 20일
0
post-thumbnail

기본 정보

  1. 배포 자동화 액션 트리거 : main에 대한 PR closed & PR에 의한 main merge

  2. 배포 웹 접속 주소 : http://13.125.33.87:3001/

  • public IP는 13.125.33.87
  • 인스턴스 접속 계정 및 비밀번호는 추후 공지하겠습니다.
  • 인스턴스 정보 : ubuntu 20.04 provided by AWS EC2
  1. 배포 자동화를 위한 secret variables 설정



1. 배포용 인스턴스 서버에 Docker 설치, 수동 프로세스 확인

이전 글 참고 - 도커허브를 사용해 배포환경으로 이전-2 : Docker pull 등 (in 오라클 클라우드)




2. 배포 자동화


Dockerfile

리액트 이미지를 생성하기 위한 정의 파일 작성

# base image 설정(as build 로 완료된 파일을 밑에서 사용할 수 있다.)
FROM node:14-alpine as build

# 컨테이너 내부 작업 디렉토리 설정
WORKDIR /app

# app dependencies
# 컨테이너 내부로 package.json 파일들을 복사
COPY package*.json ./

# package.json 및 package-lock.json 파일에 명시된 의존성 패키지들을 설치
RUN npm install

# 호스트 머신의 현재 디렉토리 파일들을 컨테이너 내부로 전부 복사
COPY . .

# npm build
RUN npm run build

# prod environment
FROM nginx:stable-alpine

# 이전 빌드 단계에서 빌드한 결과물을 /usr/share/nginx/html 으로 복사한다.
COPY --from=build /app/build /usr/share/nginx/html

# 기본 nginx 설정 파일을 삭제한다. (custom 설정과 충돌 방지)
RUN rm /etc/nginx/conf.d/default.conf

# custom 설정파일을 컨테이너 내부로 복사한다.
COPY /.nginx/nginx.conf /etc/nginx/conf.d

# 컨테이너의 80번 포트를 열어준다.
EXPOSE 80

# nginx 서버를 실행하고 백그라운드로 동작하도록 한다.
CMD ["nginx", "-g", "daemon off;"]



.nginx/nginx.conf

nginx 설정 파일 작성

server {
    listen 80;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    location / {
        # root를 /usr/share/nginx/html 을 바라보게 했으므로(Dockerfile 참고)
        # 해당 경로 아래에 배포해주면 됨
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
}



깃허브 action workflow 파일

깃허브 action의 workflow를 정의한 파일로, github가 조건 충족 시 자동으로 감지 및 이행합니다.

name: Build and Deploy

on:
  pull_request:
    branches:
      - main
    types:
      - closed

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true
  1. 메인에 대한 PR이 closed 되었을 때 workflow 실행,
  2. jobs 수행 시 PR이 merge로 끝났을 때 작업 이행

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

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PASSWORD }}

      - name: Set image name with date
        run: echo "IMAGE_NAME=choseongwoo/blockdonate-react:$(date +'%Y%m%d%H%M')" >> $GITHUB_ENV

      - name: Build and push Docker image
        run: |
          docker build -t ${{ env.IMAGE_NAME }} . 
          docker push ${{ env.IMAGE_NAME }}

러너 서버가 레포지터리를 참고하여 수행하는 작업들로
1. 도커허브 접속
2. 이미지 빌드 (+ 이미지 태그에 설정한 이름을 러너세션에서 유지되는 환경변수로 등록)
3. 이미지 도커허브에 push



      - name: SSH Remote Commands
        uses: appleboy/ssh-action@v0.1.10
        with:
          host: 13.125.33.87
          command_timeout: 200m
          username: ${{ secrets.SERVER_USERNAME }}
          password: ${{ secrets.SERVER_PASSWORD }}
          script: |
            sudo docker pull ${{ env.IMAGE_NAME }}
            sudo docker rm -f blockDonate-react
            images=$(sudo docker images | awk 'NR>4 {print $3}')
            if [ -n "$images" ]; then
              echo "$images" | xargs sudo docker rmi -f
            fi
            sudo docker run -d -p 3001:80 --name blockDonate-react ${{ env.IMAGE_NAME }}

러너 서버가 SSH 원격접속을 통해 인스턴스 서버에서 수행하는 작업들
1. swf라는 계정으로 접속
2. 도커허브에서 직전 task에서 push했던 이미지를 PULL
3. blockDonate-react라는 이름으로 실행중인 도커 컨테이너 종료 및 제거
4. docker images 명령어로 출력한 이미지 중 상단의 3개를 제외하고 모두 제거
5. nginx 80포트에 react 컨테이너 3001포트를 물려서 이미지를 컨테이너로 실행



WORKFLOW가 접속한 계정을 인스턴스 서버의 DOCKER 그룹에 추가

sudo usermode -aG dokcer swf

러너서버가 SSH를 통해 인스턴스 서버에 접속하는 계정인 swf를 서버 내 도커 그룹에 추가. (권한부여)

배포 자동화 결과 확인


profile
가용한 시간은 한정적이고, 배울건 넘쳐난다.

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

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

답글 달기