๐ Github Action + Docker + Nginx + React ์ผ๋งค CI/CD ์์ฑ๊ธฐ
๐ ๊ณ๊ธฐ
๋น์ฝํ ์๋ฒ ์ง์์ ๊ฐ๊ณ ์์๋ ์ ๋ ์ ์ฌ ํ ์ฌ๋ด ๊ตฌ์ถ๋ CI/CD ํ๊ฒฝ์ ๋ณด๊ณ ์ ๋ฌธ๋ฌผ์ ๋ง๋ ์์ฃผ๋ฏผ๋ง๋ฅ ๊น์ง ๋๋์ต๋๋ค.
์ด๋ ๊ฒ ์ข์๋ณด์ด๋ ๊ธฐ๋ฅ์ ์ ๊ฐ ์ง์ ํด๋ณด์ง ์๊ณ ์ ์ง์ฑ์ด ํ๋ฆฌ์ง ์์ฃ .
๊ทธ๋ฌ๋ค ์ด๋๋ ๋ช ๊ฐ์๊ฐ ์ฌ์ฉํ์ง ์์ ๋จผ์ง ์์ฌ์๋ ๊ฐ์ธ ์๋์ฐ ๋ ธํธ๋ถ์ด ๋์ ๋ค์ด์๊ณ ,
๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ด๋ฒ๋ฆฐ ํ ์ฐ๋ถํฌ๋ฅผ ์ค์นํด์ ํ๊ณ ์๋ ๊ฐ์ธ ํ๋ก์ ํธ๋ฅผ ์๋์ผ๋ก ๋ฐฐํฌํ ์ ์๊ฒ ๋์ ํด ๋ดค์ต๋๋ค.
์๋ฒ ์ชฝ ๊ธฐ์ด ํ๋ ์์ด ์ฝ์งํ๋ ๊ธฐ์ต์ ์ ์ ๊ฐ์ ์ํฉ์ ์์ผ์ ๋ถ๋ค์๊ฒ
์กฐ๊ธ์ด๋๋ง ๋์์ด ๋์์ผ๋ฉด ํ๋ ๋ง์์์ ์ด ๊ธ์ด๋ ๊ธฐ์ ์ ์ธ ๋ถ๋ถ์์๋ ๋ง์ด ๋ถ์กฑํ ์ ์์ต๋๋ค.
๋ํ ๋ถ๋ ๋๋ฌธ์ ๊ธฐ๋ฅ ๊ตฌํ์๋ง ์ด์ ์ ๋์๊ธฐ ๋๋ฌธ์ ๋ํ ์ผํ ๊ฒ๋ค์ ๋ง์ด ์๋ต๋์ด ๋ฐ๋ก ์ฐธ๊ณ ๋ถํ๋๋ฆฝ๋๋ค.
๐ Docker ์ค์น
// ubuntu ๋์ปค ์ค์น
$ apt-get install docker
๊ทธ๋ฅ ๋์ปค ์์ด nginx๋ฅผ ์คํํด ๋ฐฐํฌํด๋ ๋์ง๋ง ์๋ฌด๊ฒ๋ ๋ชจ๋ฅด๋ ์ ๋
์ด๋ฏธ์ง์ ์ปจํ ์ด๋๋ก ๊ตฌ๋๋๋ Docker๊ฐ ํธ๋ฆฌํ๊ฒ ๋ค๊ณ ์๊ฐํด ๋์ปค๋ก Nginx๋ฅผ ๊ตฌ๋ํ๊ธฐ๋ก ํ์ต๋๋ค.
๐ Nginx ์ปจํ ์ด๋ ์ฌ๋ฆฌ๊ธฐ
# nginx ์ด๋ฏธ์ง pull
$ docker pull nginx
# nginx ์ปจํ
์ด๋ ์์ฑ ๋ฐ ์คํ
$ docker run --name myNginx -d -p 8082:80 nginx
# docker ์คํ ์ปจํ
์ด๋ ํ์ธ
$ docker ps
๋์ปค ์ด๋ฏธ์ง๋ฅผ pull ๋ฐ์์ค๋๋ค.
๊ทธ๋ค์ ์ด๋ฏธ์ง๋ฅผ ์ปจํ ์ด๋๋ก ์์ฑ, ์คํํด์ค๋๋ค.
myNginx ๋ถ๋ถ์ ๋ณธ์ธ์ด ์ํ๋ ์ปจํ ์ด๋ ๋ช ์นญ์ด๊ณ ,
์ธ๋ถ์ ์ปจํ
์ด๋์ ํฌํธ๋ฅผ ์ด์ด์ฃผ๋ ์ต์
์ -p [์ธ๋ถํฌํธ:์ปจํ
์ด๋ ๋ด๋ถํฌํธ]
๋ก ์ค์ ํ ์ ์์ต๋๋ค.
์ ๋ 80, 8080, 8081 ํฌํธ๋ฅผ ์ด๋ฏธ ์ฌ์ฉ ์ค์ด๋ผ 8082๋ฅผ ์ฌ์ฉํ์ง๋ง
์ ์ ํ๊ณ ์๋ ํฌํธ๊ฐ ์๋ ๋ถ์ ์น ์๋ฒ ๊ธฐ๋ณธ ํฌํธ์ธ 80์ผ๋ก ์ค์ ํด ์ฃผ์๋ฉด ๋ฉ๋๋ค.
๐ Github Action, self-hosted runner
github action์ ๊ฐ๋ฐ ์ํฌํ๋ก์ฐ๋ฅผ ์๋ํ์์ผ์ฃผ๋ ๋๊ตฌ๋ก์จ ์์ฒด ์ ๊ณตํ๋ ์๋ฒ๊ฐ ์์ง๋ง
์ ๋ ๊ฐ์ธ ์๋ฒ๋ฅผ ๊ฐ๊ณ ์๊ธฐ ๋๋ฌธ์ Runner
๋ฅผ ์ง์ ์ค์นํด ๋ณด๊ฒ ์ต๋๋ค.
์์ ์ ๋ฆฌํฌ์งํ ๋ฆฌ์ ์ ์ ํ
Setting > Actions/Runners > New self-hosted runner ๋ฒํผ์ ํด๋ฆญํด ์ค๋๋ค.
์์ ์ ์ด์์ฒด์ ์ ์ํคํ ์ฒ๋ฅผ ์ ํํด ์ฃผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์น์ ํ๊ฒ Runner๋ฅผ ์ค์น ๋ฐ ์คํํ ์ ์๋ ๋ช ๋ น์ด๋ฅผ ์ ๊ณตํฉ๋๋ค.
๋ช ๋ น์ด๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์งํ๋ฉ๋๋ค.
- ํด๋ ์์ฑ ํ ์ด๋
- ์์ถํ์ผ ๋ค์ด๋ก๋
- ์์ถ ํด์
- ๋ฌ๋์ ๋ฆฌํฌ์งํ ๋ฆฌ ํ ํฐ ์ค์
- ์คํ
์ ๊ฐ ์ฒ์์ ๋ง์ฐํ๊ฒ ์ด๋ ค์ ์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ ์ ๋ง ๊ฐ๋จํฉ๋๋ค.
๊ทธ๋ฌ๋ฉด ๋ฌ๋ ํ์ผ์ ์ค์น ๋ฐ ์คํํ๊ธฐ ์ํด ์๊น ์ฌ๋ ค๋ nginx ์ปจํ ์ด๋์ ์ ์ํด ๋ณด๊ฒ ์ต๋๋ค.
# ์ปจํ
์ด๋ ์ ์
$ docker exec -it myNginx bash
exec
๋ช
๋ น์ด๋ฅผ ํตํด bash
์์ ์คํํด ์ปจํ
์ด๋์ ์ ์ํฉ๋๋ค.
๋ฌ๋ ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ๊ธฐ ์ ์ ๋ฌ๋ ํ์ผ์ ์ ํจ์ฑ์ ๊ฒ์ฆํ๊ธฐ ์ํด shasum
ํจํค์ง๊ฐ ํ์ํ๋ฐ
์ปจํ ์ด๋์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์น๊ฐ ๋์ด ์์ง ์์ ๋จผ์ ํด๊ฒฐํ๊ฒ ์ต๋๋ค.
# apt update
$ apt-get update
# shasum ์ค์น
$ apt-get install libdigest-sha-perl
๊ทธ๋ผ ๊ธฐ๋ณธ์ ์ธ ์ค๋น๊ฐ ์๋ฃ ๋์ผ๋ ์์์ ์ ๊ณตํ ๋ช ๋ น์ด๋ฅผ ์์๋๋ก ์คํ์์ผ ํ์ผ์ ๋ฐ์ ๋ค ์์ถ์ ํด์ ํฉ๋๋ค.
๐ Runner, Must not run with sudo
๋ค์ Configure ๋ถ๋ถ์ ๋ช ๋ น์ด๋ฅผ ์คํ์ํค๋ฉด ๋๋๋ฐ
Must not run with sudo๋ผ๋ ๊ฒฝ๊ณ ๊ฐ ๋จ๋ฉฐ ํ ํฐ ์ค์ ์ด ์ ๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
์ด๋ ๋ฃจํธ ์ฌ์ฉ์๋ก ๋ช
๋ น์ด๋ฅผ ์คํํด์ ๋จ๋ ๊ฒฝ๊ณ ๋ก
๋ค์๊ณผ ๊ฐ์ ํ ํฐ ์ค์ ๊ณผ ๋ฌ๋ ์คํ ์คํฌ๋ฆฝํธ ํ์ผ์ ์คํ์ ๋ง๋ ์กฐ๊ฑด๋ฌธ์ด ์ฌ์ด์ ธ ์์ต๋๋ค.
- run-helper.sh
- config.sh
- run-helper.sh.template
๋ณด์ ๋๋ฌธ์ ์ฌ์ด์ง ์ฝ๋๋ก ๋ณด์ด๋,
๊ฐ์ธ ์๋ฒ ์ฐ์ต์ฉ์ผ๋ก ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด RUNNER_ALLOW_RUNASROOT๋ฅผ ์ ์ญํ๊ฒฝ๋ณ์๋ก ๋ฑ๋กํด ํด๊ฒฐํ์ต๋๋ค.
# ์ ์ญํ๊ฒฝ๋ณ์ ๋ฑ๋ก
$ export RUNNER_ALLOW_RUNASROOT="1"
# ํ๊ฒฝ๋ณ์ ํ์ธ
$ echo $RUNNER_ALLOW_RUNASROOT
์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์๋ค๋ฉด ์ ๊ณตํ Configure ๋ช ๋ น์ด๋ฅผ ์คํํด ํ ํฐ์ ๋ฑ๋กํด ์ฃผ๊ณ
๋ฌ๋ ์ค์ ์ ๋ง๋ฌด๋ฆฌํด ์ฃผ๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ๋ฉด์ ๋ณผ ์ ์์ต๋๋ค.
์ ๋ ๊ท์ฐฎ์์ ์ ๋ถ ์ํฐํค๋ก ์คํตํ์ต๋๋ค.
์ค์ ๊น์ง ๋ง์ณค์ผ๋ ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ด๋ก ๋ฌ๋๋ฅผ ์คํ์์ผ ๋ณด๊ฒ ์ต๋๋ค.
$ nohup ./run.sh &
$ ./run.sh
๋ก ๊ทธ๋ฅ ์คํ์์ผ๋ ๋์ง๋ง
nohup
์ ํตํด ํฐ๋ฏธ๋์ ์ข
๋ฃํด๋ ์คํ๋๋๋ก ํ๊ณ
& ์ต์ ์ ํตํด ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํ๋๋๋ก ํฉ๋๋ค.
์ ์์ ์ผ๋ก ์คํ๋์๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊นํ๋ธ์ ๋ฌ๋๊ฐ idle ์ํ๋ก ํ์๋๊ฒ ๋ฉ๋๋ค.
๐ Github Action, workflow
์ด์ ๋ฌ๋ ์ค๋น๋ ๋๋ฌ๊ณ ์ํ๋ ์๋ํ ์ํฌํ๋ก์ฐ๋ฅผ ์์ฑํ๊ธฐ ์ํด
ํ๋ก์ ํธ ํด๋ ๋ฃจํธ์ ๋ค์๊ณผ ๊ฐ์ด ํด๋์ yml
ํ์ผ์ ์์ฑํด ์ค๋๋ค.
๊นํ๋ธ์์ ์ํฌํ๋ก์ฐ๋ฅผ ์ธ์์ํค๊ธฐ ์ํด ํด๋๋ช
์ ๊ผญ .github/workflows
๋ก ์ง์ ํด ์ฃผ์ธ์
๊ทธ๋ฆฌ๊ณ ๋ค์๊ณผ ๊ฐ์ด ํ์ผ์ ์์ฑํด ์ค๋๋ค.
๋ถ๋ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ธ ๊ฒ๋ง ์ฃผ์์ผ๋ก ์ค๋ช ํ๊ณ ๋๋จธ์ง์ ๋ํ ์ค๋ช ์ ์๋ตํ๊ฒ ์ต๋๋ค.
name: CD
on:
push:
# main ๋ธ๋์น์ ํธ์ํ๋ฉด ์๋
branches: [ main ]
jobs:
build:
runs-on: self-hosted
steps:
# ์ ๊ณตํ๋ checkout ์ก์
์ ์ด์ฉํด ๋ฆฌํฌ์งํ ๋ฆฌ ๊ฐ์ ธ์ค๊ธฐ
- uses: actions/checkout@v3
- run: pwd
- run: ls -al
# ๋
ธ๋ ์ก์
์ ํตํด npm ๋ช
๋ น์ด ์ฌ์ฉ
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm install
- run: npm run build
๊ทธ๋ค์ ํ ์คํธ๋ฅผ ์ํด ์ปค๋ฐ ํ ํธ์ํ๋ฉด ๊นํ๋ธ์์ ์ฑ๊ณต์ ์ผ๋ก ๋น๋๊น์ง ๋ง๋ฌด๋ฆฌ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๐ Nginx ์ค์
์๋์ผ๋ก ๋น๋๊น์ง ์๋ฃํ๋ค๋ฉด ์ ์ ํ์ผ๋ค์ ์๋นํ ์น ์๋ฒ์ธ Nginx ๋ํ ์ค์ ํด ์ฃผ์ด์ผ๊ฒ ์ฃ ?
# default.conf
server{
listen 80;
listen [::]:80;
server_name localhost;
location / {
# ๋น๋ ํ์ผ์ด ์กด์ฌํ๋ ํด๋ ๊ฒฝ๋ก
root /actions-runner/_work/runner-ex/runner-ex/build;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
nginx ์ค์ ํ์ผ์ listen
๋ถ๋ถ์ ์ปจํ
์ด๋๋ฅผ ์์ฑํ๋ฉฐ ๋ช
์ํ๋ ์ปจํ
์ด๋ ๋ด๋ถ ํฌํธ๋ฅผ ์์ฑํด ์ฃผ๊ณ
root ๋ถ๋ถ์ ๋น๋ ์ฐ์ถ๋ฌผ์ด ์กด์ฌํ๋ build
ํด๋ ์์น๋ฅผ ์์ฑํด ์ฃผ๋ฉด ๋์
๋๋ค.
๊ทธ๋ฐ๋ฐ nginx ํ์ผ์ ๊ณ ์ ์ผ๋ก ๋ฐ์๋์ด๋ ๋์ง๋ง ์์ ์ด ํ์ํ ๋
workflow์ ํฌํจ๋์ด ์๋ํ๋๋ค๋ฉด ์ ๋ง ํธํ๊ฒ ์ฃ ?
# ๊ธฐ์กด ์ค์ ํ์ผ ์ญ์
- run: rm /etc/nginx/conf.d/default.conf
# checkout ํ๋ฉฐ ๋ฐ์์จ ์ค์ ํ์ผ ์ด๋
- run: mv default.conf /etc/nginx/conf.d/
# ๋ณ๊ฒฝ์ฌํญ ์ ์ฉ์ ์ํ nginx ์ฌ์คํ
- run: service nginx reload
๊ทธ๋ผ deploy.yml
ํ์ผ์ steps์ ์์ ๊ฐ์ ์ฝ๋๋ฅผ ์ถ๊ฐํด ์ฃผ๋๋ก ํฉ๋๋ค.
์ด์ ํธ์ํ๋ฉด ์ฑ๊ณต์ ์ผ๋ก ๋ง๋ฌด๋ฆฌ ๋์์ ํ์ธํ ์ ์์ต๋๋ค.
๊ทธ๋ผ ์ ๋๋ก ๋ฐฐํฌ๊ฐ ๋์๋ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค.
์ ip ์ฃผ์์ ์ปจํ ์ด๋ ์ธ๋ถ ์ ์ ํฌํธ์ธ 8082๋ฅผ ์ด์ฉํด ์ ์ํด ๋ณด๋ ์ ์๋ํฉ๋๋ค!
๊ธ์ด ์๊ฐ๋ณด๋ค ๋ง์ด ๊ธธ์ด์ก๋๋ฐ ์ฒ์์ผ๋ก ๋์ ํ์๋ ๋ถ๋ค๊ป ๋ง์ ๋์์ด ๋์์ผ๋ฉด ํฉ๋๋ค.
์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
๋๊ธ