이번에 토이프로젝트중 하나로 사내 서비스용 챗봇서비스를 만들기 시작했다. 그런데 스케일 아웃을 고려할 필요 없는 작은 규모의 서비스이기 때문에 가장 간단한 배포 방법을 찾아보기로 했다.
이렇다 보니, 기존에 사용하던 도커나 쿠버네티스보다 더 간단한 Github Action 을 이용해서 배포하는 방법을 적용하게 되었다.
서버를 이미 발급받아서, ssh 로 접근 가능한 상태라고 가정한다
가장 먼저해야 할 부분은 Github 에서 서버를 조작할 수 있는 환경을 만들어야 한다. 그 방법으로 Github Action Runner 를 서버에 설치하는 방법을 선택했다.
<repository url>/settings/actions/runners/new
로 바로 들어가거나 github -> 상단 setting -> Actions -> Runnes
순서로 들어가기
자신의 OS 에 맞게 선택 (필자는 CentOS 이기 때문에 Linux 로 선택)
하단에 노출되는 Download 스크립트를 복사해서 서버에서 실행
github Runner 를 service 로 등록해서 서버가 부팅되면 자동 실행되도록 아래 스크립트 실행
sudo ./svc.sh install
sudo ./svc.sh start
<repository url>/settings/actions/runners
로 바로 들어가거나 github -> 상단 setting -> Actions -> Runners
순서로 들어가기Github workflow 는 .github/workflows
하위에 yaml
확장자의 파일을 생성해야 한다.
Github Action 문법은 https://docs.github.com/en/actions 에서 참고하자. 문법을 여기에서 다루기보다는 문서를 쭉 살펴보는 것이 좋을 것 같다.
필자는 node 서버를 배포하는 것이기 때문에, 자신의 서버에 맞춰야 한다.
.github/workflows/deploy.yml
파일에 아래와 같이 정의했다.
name: App install and start
concurrency:
group: production
cancel-in-progress: true
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: [ self-hosted ]
steps:
- uses: actions/checkout@v2
with:
clean: false
- name: Use Node.js 16.x
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Install dependencies
working-directory: service
run: npm install
- name: Stop old server (ignore error)
run: |
killall -9 node || true
- name: Remove old server in ~/soruce (ignore error)
run: |
rm -rf ~/source || true
- name: Copy new server to ~/soruce
run: |
mkdir -p ~/source
cp -R ./ ~/source
- name: Run new server (in background)
env:
RUNNER_TRACKING_ID: ""
run: |
cd ~/source
nohup npm run start </dev/null >/dev/null 2>&1 &
하나씩 살펴보도록 하자.
concurrency:
group: production
cancel-in-progress: true
동시성 설정이다. 배포 workflow 이기 때문에, 여러개의 workflow 가 실행될 때 맨 마지막 workflow 만 남기고 모두 취소한다. (어차피 중간에 실행된 workflow 는 모두 덮어씌워져 없어지니까)
on:
push:
branches: [ main ]
workflow_dispatch:
해당 workflow 의 실행 조건이다
- uses: actions/checkout@v2
with:
clean: false
github repository 를 clone 혹은 fetch 한다
clean: false
을 설정했다- name: Use Node.js 16.x
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Install dependencies
working-directory: service
run: npm install
부가적인 환경설정
- name: Stop old server (ignore error)
run: |
killall -9 node || true
- name: Remove old server in ~/soruce (ignore error)
run: |
rm -rf ~/source || true
기존에 배포된 서버 Clean Up
|| true
추가- name: Copy new server to ~/soruce
run: |
mkdir -p ~/source
cp -R ./ ~/source
runner 폴더에 저장된 repository 를 ~/source 로 복사
mkdir -p ~/source
를 먼저 실행해서 폴더를 만들어 둔다- name: Run new server (in background)
env:
RUNNER_TRACKING_ID: ""
run: |
cd ~/source
nohup npm run start </dev/null >/dev/null 2>&1 &
이 Article 에서 가장 핵심인 부분이다. (삽질을 많이 했다)
RUNNER_TRACKING_ID=""
를 등록한다. Runner 가 종료될 때 자동으로 붕뜨게 된 프로세스(=orphan process)를 모두 닫는데, background 로 띄워둔 서버도 같이 닫히게 된다. 비공식적인 부분이지만, 위 값을 등록해서 이를 방지한다.nohup
은 로그아웃 신호를 무시하는 프로세서이다npm run start
가 원래 서버를 구동하기 위한 명령어였다. (이 부분은 구성에 따라 수정이 필요하다)</dev/null
: 프로그램의 입력을 받지 않도록 함>/dev/null
: 프로그램의 출력을 받지 않도록 함2>&1
: 프로그램의 에러를 출력으로 보냄, (위의 >/dev/null
를 통해 무시하도록 함)&
해당 프로세스를 백그라운드로 실행여기까지 작업했으면 workflow 설정이 약간 복잡하긴 하지만, Github 을 통해 서버 배포를 할 수 있게 된다.
물론 scale out 을 고려하지 않기 때문에 가능한 구성이다.
제 은인이십니다. 감사합니다 감사합니다 감사합니다. RUNNER_TRACKING_ID: "" 이걸 찾고 있었습니다.