배포 자동화를 해놓지 않았을 때
- 인스턴스 접속
- git pull
- 백엔드 폴더에서 yarn install -> 배포
- 프론트 폴더에서 yarn install -> yarn build -> 배포
배포 자동화를 해놓지 않았을 때는 위 과정의 반복이었다. 조그마한 변경이 있어도 매번 이렇게 해야해 너무 번거로웠다.
그래서 Github Actions를 이용해 CI/CD를 구축해보기로 했다.
CI/CD를 처음 시도해봤기 때문에 어디서부터 어떻게 해야할지 참 막막했다. 현재 오라클 클라우드를 사용 중인데 오라클에서 제공하는 OCI DevOps는 유료 서비스여서 시도해보지 못했고, OCI 블로그에 나와있는 방법이나 OCI CLI를 이용하는 방법을 모두 시도해보았으나 실패했다.
그래서 평소대로 ssh로 연결한 후 배포가 진행되도록 해보았다.
ssh 연결해서 인스턴스에 접속하기
Github Actions에서 ssh로 접속하기 위해서는 SSH Remote Commands라는 action을 사용해주면 된다.
ppk 파일을 rsa로 변경하기
ssh-action을 사용하기 위해서는 putty로 생성했던 ppk 파일을 rsa 형식으로 변경해주어야 한다.
PuTTYgen을 실행해서 기존의 ppk 키 파일을 불러온다.
Conversions - Export OpenSSH key를 누르고 원하는 곳에 저장을 해주면 된다.
secret 설정
본격적으로 yaml 파일을 작성하기 전에, Github Actions에서 사용할 환경 변수를 설정해주어야 한다.
레포지토리의 Settings - Secrets and variables - Actions에서 New repository secret을 눌러 설정해줄 수 있다.
이런 식으로 설정해주면 되고, 포트 번호 외에도 host, key, passphrase, username을 추가적으로 등록해주었다. (key에는 아까 만들었던 rsa 키 파일의 내용을 BEGIN과 END라인까지 포함해서 넣어주면 된다.)
ssh 접속
secret까지 다 등록해주었다면 아래처럼 ssh 연결을 할 수 있다. 연결 후 할 동작들을 script에 쭉 적어주면 된다.
.github/workflows/deploy.yml
name: deploy
on:
push:
branches: ['master']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.3.0
- name: execute remote ssh
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_SSH_HOST }}
username: ${{ secrets.REMOTE_SSH_USERNAME }}
key: ${{ secrets.REMOTE_SSH_KEY }}
passphrase: ${{ secrets.REMOTE_SSH_PASSPHRASE }}
port: ${{ secrets.REMOTE_SSH_PORT }}
script: |
whoami
Workflow 작성
특정 브랜치에 대해서만 Github Actions가 trigger되도록 하기
master 브랜치에 push되었을 때만 실행될 수 있도록 하자.
name: deploy
on:
push:
branches: ['master']
백엔드 서버 배포
.github/workflows/deploy.yml
name: deploy
on:
push:
branches: ['master']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.3.0
- name: execute remote ssh & deploy backend server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_SSH_HOST }}
username: ${{ secrets.REMOTE_SSH_USERNAME }}
key: ${{ secrets.REMOTE_SSH_KEY }}
passphrase: ${{ secrets.REMOTE_SSH_PASSPHRASE }}
port: ${{ secrets.REMOTE_SSH_PORT }}
script: |
whoami
cd ../../usr/KORrection/back
sudo git pull origin master
export NVM_DIR=~/.nvm
source ~/.nvm/nvm.sh
yarn install
pm2 restart back-server
ssh로 성공적으로 연결했다면 배포에 필요한 작업들을 script에 적어주면 된다. 위의 내용은 백엔드 서버를 배포하는 스크립트이다.
백엔드 폴더로 이동 후 git pull을 받아오고, 배포 작업을 진행한다.
이 때 주의할 점은 nvm.sh를 실행해주어야 한다는 것이다. 이렇게 하지 않으면 yarn이나 pm2에 대해 command not found 에러가 발생할 수 있다.
프론트엔드 배포
name: frontend CD
on:
push:
branches: ['master']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: execute remote ssh & deploy frontend server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_SSH_HOST }}
username: ${{ secrets.REMOTE_SSH_USERNAME }}
key: ${{ secrets.REMOTE_SSH_KEY }}
passphrase: ${{ secrets.REMOTE_SSH_PASSPHRASE }}
port: ${{ secrets.REMOTE_SSH_PORT }}
script: |
whoami
cd ../../usr/KORrection/front
sudo git pull origin master
export NVM_DIR=~/.nvm
source ~/.nvm/nvm.sh
yarn install
yarn build
sudo systemctl reload nginx
비슷한 과정으로 프론트 배포도 해줄 수 있다.
특정 폴더에 대해서만 Github Actions가 trigger되도록 하기
back 폴더에서 변화가 생겼을 때는 백엔드 코드만, front 폴더 내에서 변화가 생겼을 때는 프론트엔드 코드만 배포되도록 하고 싶었다.
그래서 back.yml, front.yml로 파일을 따로 작성해주고, paths를 지정해주었었다. 의도대로 동작하지 않아 찾아보니 paths는 같은 워크플로우에서 여러 path를 지정해줄 때 쓰는 것이었다.
https://stackoverflow.com/questions/67941070/github-action-trigger-on-multiple-on-push-paths
path-filter라는 액션을 사용해주면 내가 의도한대로 할 수 있었다.
.github/workflows/deploy.yml
name: deploy
on:
push:
paths:
- 'back/**'
- 'front/**'
branches: ['master']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.3.0
- uses: dorny/paths-filter@v2.11.1
id: changes
with:
filters: |
back:
- 'back/**'
front:
- 'front/**'
- name: execute remote ssh & deploy backend server
if: steps.changes.outputs.back == 'true'
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_SSH_HOST }}
username: ${{ secrets.REMOTE_SSH_USERNAME }}
key: ${{ secrets.REMOTE_SSH_KEY }}
passphrase: ${{ secrets.REMOTE_SSH_PASSPHRASE }}
port: ${{ secrets.REMOTE_SSH_PORT }}
script: |
whoami
cd ../../usr/KORrection/back
sudo git pull origin master
export NVM_DIR=~/.nvm
source ~/.nvm/nvm.sh
yarn install
pm2 restart back-server
- name: execute remote ssh & deploy frontend server
if: steps.changes.outputs.front == 'true'
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_SSH_HOST }}
username: ${{ secrets.REMOTE_SSH_USERNAME }}
key: ${{ secrets.REMOTE_SSH_KEY }}
passphrase: ${{ secrets.REMOTE_SSH_PASSPHRASE }}
port: ${{ secrets.REMOTE_SSH_PORT }}
script: |
whoami
cd ../../usr/KORrection/front
sudo git pull origin master
export NVM_DIR=~/.nvm
source ~/.nvm/nvm.sh
yarn install
yarn build
sudo systemctl reload nginx
한 파일에 모든 내용을 써주고, paths filter를 통해 변경이 일어난 부분이 back인지 front인지를 확인해주고 if를 사용해 조건에 맞을 때만 실행될 수 있도록 해주면 된다.
이렇게 작성해주면 back 폴더 내에서만 변경이 일어났을경우 아래처럼 백엔드 서버만 배포해주는 것을 확인할 수 있다.
References
https://github.com/marketplace/actions/ssh-remote-commands
[ssh] putty ppk 파일을 openssh 개인키로 변환하기
[Github, CI/CD] 특정 파일이나 폴더에 대해서만 Github Actions가 trigger되는 방법
Github Action PM2 배포시 pm2 command not found
https://stackoverflow.com/questions/67941070/github-action-trigger-on-multiple-on-push-paths
https://github.com/marketplace/actions/paths-changes-filter
'DevOps' 카테고리의 다른 글
오라클 클라우드 사용하기 - (3) 도메인 연결, 구글 로그인 (1) | 2022.10.13 |
---|---|
오라클 클라우드 사용하기 - (2) 프로젝트 배포(React, Node.js) (0) | 2022.10.13 |
오라클 클라우드 사용하기 - (1) 인스턴스 생성, ssh 접속 (0) | 2022.10.11 |