Github Actions로 React 자동 배포하기 (Nginx)

krkorklo·2022년 10월 18일
0

전에는 SSR로 구현하고 express를 배포했었는데, 이번에는 프/백 따로 배포하면서 React를 배포해야했다.

배포까지 크게 다른 부분은 없었다. 그냥 ncloud에서 받은 서버로 ssh 접속하고 git clone한 다음에 npm start하면 실행이 된다.

하지만! 계속 npm start로 하는 것보다 static한 빌드된 파일을 가벼운 서버에서 돌리기 위해 nginx를 사용하게 됐다.

Nginx

  • 웹 서버 소프트웨어
  • single thread로 비동기 non-blocking IO 이벤트 기반으로 요청을 처리해 적은 자원으로 효율적인 트래픽 처리

1. HTTP 서버로서 정적 파일을 처리

  • HTML, CSS같은 정적 리소스에 대한 요청을 처리 가능
  • React의 빌드된 파일들도 올릴 수 있음 (index.html 렌더링)

2. Reverse Proxy Server로서 클라이언트와 서버를 중개

  • client request와 server response를 중개

Nginx 설정

우선 빌드된 파일을 Nginx에 올리기 위해 클라이언트 폴더에서 빌드를 해줬다.

apt-get install nginx

이제 nginx를 설치하고 nginx 설정을 위한 스크립트를 작성한다.

sudo vi /etc/nginx/sites-enabled/default

이미 기본으로 작성된 스크립트들이 있을텐데 나는 그냥 지우고 필요한 사항만 작성해줬다.

server {
  listen 80;

  location / {
    root    /github_repository/client/build; # 빌드된 파일이 있는 경로
    index   index index.html;
    try_files $uri $uri/ /index.html;
  }

  location /api {
    proxy_pass      http://[SERVER_URL];
  }
}
  • listen [port]
    • 해당 port로 들어오는 요청을 받는다는 의미로 http 기본 port 80으로 설정해준다.
  • location /[route]
    • 해당 route로 들어오는 요청을 처리하게 된다.
  • `root [route]
    • nginx 웹 서버가 파일을 찾는 경로로 build 폴더의 위치를 지정해 빌드 파일을 찾을 수 있게 해준다.
  • try_files
    • request에 대해 일치하는 path를 앞에서부터 순서대로 비교한 뒤 root에 존재하는 path를 rewrite
    • 정적 파일이 없는 url인 경우 index.html을 리턴
  • proxy_pass
    • reverse proxy 설정으로 지정된 location으로 받은 요청을 해당 proxy로 연동해서 보내게 된다.

reverse proxy?

  • forward proxy
    • 인터넷에 접속할때 proxy 서버를 거쳐서 인터넷에 연결되는 것
    • 클라이언트가 인터넷에 직접 접근하는 것이 아니라 forward proxy가 요청을 받고 인터넷에 연결한 뒤 결과를 클라이언트에게 전달
    • end point가 실제 서버 도메인이고 클라이언트의 정보가 감춰진다.

  • reverse proxy
    • 클라이언트가 서버가 제공하는 서비스에 접근할때 proxy 서버를 거쳐서 내부로 들어오는 것
    • 클라이언트가 인터넷에 데이터를 요청하면 reverse proxy가 요청을 받아 내부에서 데이터를 처리한 뒤 클라이언트에게 전달
    • 프록시 서버의 IP만 공개해 보안적인 측면에서 이점을 가질 수 있고 캐싱이나 트래픽 분산 기능을 추가할 수도 있다.
    • end point가 프록시 서버 도메인이고 서버의 정보가 감춰진다.

Nginx 실행

스크립트 작성하고 실행하기만 하면 끝이다.

sudo service nginx start

403 forbidden

처음부터 오류가 떴다.
403 forbidden으로 권한이 없다고 떠서 보니까 index.html에 execute 권한이 없었다.
실행하고자하는 빌드 파일까지의 경로가 모두 execute 권한이 있어야 한다고 해서 권한을 부여해주니까 해결!

80 포트 접속 안됨

listen으로 80 포트를 열어두고, netstat으로 80 port 열린 것도 확인했는데 도저히 접속이 안 됐다.

이거가지고 진짜 하루종일 헤맸는데
다음날 아침에 일어나서 보니까,,,

ACG에서 port 설정을 안 해뒀었다.

😇

설정해주니까 해결,,,

Github Actions

nginx로 배포하고 개발하는 과정에서 github에서 업데이트된 파일 pull받고, Nginx에 빌드파일 올리고, nginx restart하는 과정이 매우 번거로웠다. 그래서 github actions를 사용해서 자동화를 하기로 했다.

  • github action은 github에서 제공하는 CI(Continuous Integration)/CD(Continuous Deployment)를 위한 서비스
  • workflow를 자동화할 수 있도록 도와주는 도구
  • 어떤 이벤트가 발생했을 때 특정 작업이 일어날 수 있게 하거나 주기적으로 어떤 작업을 반복해서 실행할 수 있음
    • PR을 생성했을 때 변경 사항에 문제가 없는지 검사할 수 있음
    • 새로운 코드가 push 되면 build하고 deploy 할 수 있음

workflows

  • 작업 과정으로 하나의 코드 저장소에 여러 개의 워크플로우(yml) 파일을 정의 가능

jobs

  • 독립된 가상 머신, 컨테이너에서 돌아가는 하나의 처리 단위로 하나의 워크플로우는 적어도 한 개 이상의 작업으로 구성
  • runs-on으로 실행 환경을 지정

steps

  • 하나의 작업이 여러 단계의 명령을 순차적으로 실행하는 경우 정의
  • command나 script는 run 속성을 사용, 액션을 사용할 때는 uses 속성을 사용

actions

  • workflow의 가장 작은 요소

ssh로 원격 접속을 하고 command를 입력해야했다. ssh-action을 사용해서 간단하게 작성이 가능했다.

name: React build
on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - name: SSH-deploy
        uses: appleboy/ssh-action@master 
        with: 
          host: ${{ secrets.REMOTE_IP }} # ssh 접속용 ip
          username: ${{ secrets.REMOTE_SSH_ID }} # root
          password: ${{ secrets.REMOTE_SSH_KEY }} # ssh 접속용 password
          port: ${{ secrets.REMOTE_SSH_PORT }} # ssh 접속용 port
          script: |
            sh deploy.sh
# deploy.sh
cd /repository
git pull origin main
cd /client
yarn build
sudo service nginx restart

main 브랜치로 push가 되면 서버에 작성해놓은 deploy.sh가 실행되도록 하는 코드이다. secrets는 setting에서 설정해줄 수 있다.

그런데 이렇게 작성하면 오류가 난다.

왜,,,🥹

알고보니 github action에서 ubuntu 18.04 버전이 decrecated되었다고 한다.
그래서 16.04 버전으로 바꿔주니 성공했다ㅎㅎ


참고자료
https://bcp0109.tistory.com/m/194
https://kaizen8501.tistory.com/m/260

0개의 댓글