๊นํ๋ธ ์ก์ ๊ณผ ๋์ปค๋ฅผ ์ด์ฉํด ๋ฆฌ์กํธ ํ๋ก์ ํธ ์๋ ๋ฐฐํฌ ํ๊ฒฝ์ ๊ตฌ์ถํด๋ณด๊ธฐ. ๋์ปค์ ๊ดํ ์ธ๊ฐ์ ์ ์ญํ๊ณ ์ผ๋ง ์๋์๋ ์กฐ๊ธ ๋ฃ๋ค ๋ง์๊ณ , ๊ทธ ์ดํ๋ก CI/CD์ ๋ํ ๊ฒฝํ์ด ์์๊ธฐ ๋๋ฌธ์. ์ด ๊ธฐํ์ ์ ๋ฆฌ๋ฅผ ํด๋์ผ๊ฒ ๋ค๋ ์๊ฐ์ด ๋ ๋ค. ๋ด๊ฐ ํ ๋ถ๋ถ์ ํ๋ก ํธ ๋ ํฌ์งํ ๋ฆฌ ๊ด๋ จ ๋ฟ์ด์ง๋ง ํ์์ ๊ตฌ์ถํ ์ ์ฒด์ ์ธ ํ๋ฆ์ ์ ์ด๋ณด๊ฒ ์ต๋๋ค. ์ ์ฒด์ ์ธ ์ฝ๋๋ ์ด์ ์ ๊ณ ์ค๋ฝ ํ๋ก์ ํธ ํ๋ฉด์ ์ฐฌ์ง์ด๊ฐ ์ธํ ํ๊ฑฐ ๋ณด๊ณ ์ด์ฌํ ๋ฏ์ด์ ๋ฐฐ์์์.
์ฌ์ฉํ ๊ฒ๋ค
- Github Actions
- Docker, Docker Compose
- Nginx
์ ์ฒด์ ์ธ ํ๋ฆ
- ํ๋ก ํธ ๋ ํฌ์งํ ๋ฆฌ์ main ๋ธ๋์น์ push
- Github Actions์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๋ฉด ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ ๋์ปค ํ๋ธ๋ก push
- ์๋ก ๋ฐฐํฌ๋ฅผ ์ํ ๋ Deploy ๋ ํฌ์งํ ๋ฆฌ์ main์ push ํน์ release
- Github Actions์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๋ฉด ์์ฑํ Docker Compose ํ์ผ ์คํ
๋จผ์ , ํ๋ก ํธ ๋ ํฌ์งํ ๋ฆฌ
Github Actions์์ Main ๋ธ๋์น์ ํธ์ฌ(Event) ์ ์คํํ ์์ (Workflow)๋ฅผ ์ค์ ํ๋ค.
๋ฃจํธ ๋๋ ํ ๋ฆฌ์ .github/workflows ์์น์ yaml ํ์ผ์ ์์ฑํ๋ค. ์ด๋ฒ ๊ฒฝ์ฐ์ prod-deploy.yml
์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ง๋ค์๋ค.
prod-deploy.yml
name: Docker
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
# ๋์ปค ์ด๋ฏธ์ง์ env ํ์ผ ํฌํจ
- name: Create .env file
run: |
touch .env
echo REACT_APP_KAKAO_REST_API_KEY=${{ secrets.REACT_APP_KAKAO_REST_API_KEY }}\ >> .env
# ๋์ปค ๋ฉํ
- name: Docker meta
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v1
with:
images: sanbonai06/bankids-client
tag-semver: |
{{version}}
{{major}}.{{minor}}
# ๋์ปค ๋น๋ ๊ด๋ จ ์
์
- 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_TOKEN }}
# ๋์ปค์ด๋ฏธ์ง ๋น๋ํ๊ณ ํ๋ธ๋ก ํธ์ฌ
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.prod
platforms: linux/amd64
push: true
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
ํ๋์ฉ ๋ฏ์ด๋ณด๊ธฐ๋ก.
Checkout
- github actions๋ ํด๋น ํ๋ก์ ํธ๋ฅผ ๋ฆฌ๋ ์ค ํ๊ฒฝ์ checkoutํ๊ณ ๋์ ์คํ ํ๋ค.
- ์ฐ๋ฆฌ๊ฐ ๊น์์ ๋ธ๋์น๋ฅผ ์ฌ์ฉํ ๋ checkout ํ๋๊ฒ์ฒ๋ผ... ํ์๋ผ๊ณ ํจ.
uses
๋ผ๋ ํค์๋๋ฅผ ํตํด ๋๊ตฐ๊ฐ๊ฐ ๋ง๋ค์ด๋์ actions์ ๋ถ๋ฌ์ ์ฌ์ฉํ ์ ์๋ค.
Create .env file
- ๋ฆฌ์กํธ ํ๋ก์ ํธ ๋ด์์ ์ฌ์ฉํ๊ณ ์๋ .env ํ๊ฒฝ๋ณ์ ํ์ผ์ ๋ฆฌ๋ ์ค ํ๊ฒฝ์๋ ์ง์ ๋ณต์ฌ๋ฅผ ํด์ ๋ฃ์ด์ค๋ค.
- ๊ธฐ์กด์ ์๋ ์ฝ๋์์ ๊ฐ์ ธ์๋๋ฐ, ๊ตฌ๊ธ๋ง ํด๋ ๋น์ทํ ๊ฒฝ์ฐ๋ฅผ ์ฐพ๊ธฐ๊ฐ ์ฝ์ง ์๋ค. ์ข ๋ ์์๋ด์ผ๋ ๋ฏ.
Docker meta
- ๊น๊ณผ ๊นํ๋ธ ์ด๋ฒคํธ์์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ์์ ์ด๋ผ๊ณ ํ๋ค.
- ๋ง์ง๋ง step์์ tags์ labels์ ์ด ๋จ๊ณ์์ ๋์จ ์ ๋ณด๋ค์ด ์ฌ์ฉ๋๋ ๊ฒ ๊ฐ์.
Docker build
- ์ดํ ์ธ step์ ๋์ปค ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ๊ณ ํ๋ธ๋ก ํธ์ฌํ๋ ์์ ์ ๋ํ ๋ด์ฉ์ด๋ค.
- ๋์ปคํ๋ธ ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ ํฌ์งํ ๋ฆฌ secret์ ์ ์ฅํ๊ณ ๋์ปค ํ๋ธ ๋ก๊ทธ์ธ์ ์ฌ์ฉํ๋ค.
- ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ๊ณ ํธ์ฌ๋ฅผ ํ๋ค. ์ ์ฅ๋์ด ์๋ ๋์ปคํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํด์ค๋ค.
์ฐธ๊ณ 1
Dockerfile.prod
๋์ปคํ์ผ์ ์ปจํ ์ด๋์ ์ค์นํด์ผ ํ๋ ํจํค์ง, ์์ค, ๋ช ๋ น์ด ๋ฑ์ ๊ธฐ๋กํ ํ๋์ ํ์ผ์ด๋ค. ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ ๋ ์ด ํ์ผ์ ์ด์ฉํด์ ๋น๋ํ๋ค.
FROM node:14 AS builder
# set working directory
WORKDIR /app
# install app dependencies
#copies package.json and package-lock.json to Docker environment
COPY package-lock.json ./
COPY package.json ./
# Installs all node packages
RUN npm ci
# Copies everything over to Docker environment
COPY . ./
RUN npm run build
#Stage 2
#######################################
#pull the official nginx:1.19.0 base image
FROM nginx:1.19.0
#copies React to the container directory
# Set working directory to nginx resources directory
# WORKDIR /usr/share/nginx/html
COPY config/nginx/default.conf /etc/nginx/conf.d/default.conf
# Remove default nginx static resources
RUN rm -rf ./usr/share/nginx/html/*
# Copies static resources from builder stage
COPY --from=builder /app/build /usr/share/nginx/html/
# Containers run nginx with global directives and daemon off
EXPOSE 3000
ENTRYPOINT ["nginx", "-g", "daemon off;"]
๋์ปคํ์ผ๋ ๋ฃจํธ ๋๋ ํ ๋ฆฌ์ ์์ฑํด์ค๋ค. ๊ธฐ์กด ์ฝ๋์์ ๊ฑด๋ค ๊ฒ ์์ด ๊ฐ์ ธ์๋ค. ๋์ปคํ์ผ์ ๋ํ ๋ด์ฉ์ ์ธ๊ฐ์์ ๋ค์๊ฒ ์์ผ๋ฏ๋ก ์์ธํ ์ค๋ช ์ ํจ์ฐ.. ํน์ด์ฌํญ์ผ๋ก๋ nginx๊น์ง ๊ฐ์ด ์ปจํ ์ด๋ ์์ ๋ง์ ๋ฃ๋๋ค.
- nginx๋ base image๋ก ์ฌ์ฉํ ์ ์๋๋ก ๋์ด ์์ผ๋ฏ๋ก ๊ฐ์ ธ์ค์.
- ํ๋ก์ ํธ ํ์ผ๋ด์
default.conf
๋ก ์์ฑํด๋๊ณ , ๋ฆฌ๋ ์ค์ nginx ๋๋ ํ ๋ฆฌ๋ก ๋ณต์ฌํด์ค๋ค. - ๋น๋๋ ํ์ผ๋ ๋ฆฌ๋ ์ค์ ํด๋น ๋๋ ํ ๋ฆฌ๋ก ๋ณต์ฌํด์ค๋ค. ํด๋น ๋๋ ํ ๋ฆฌ๋ nginx ์ค์ ํ์ผ์์ root ๊ฒฝ๋ก์ ๋ง์ถ์ด ์ค๋ค. nginx์ ๋ํ ํฌ์คํ ๋ ์ด์ ์ ํด๋จ๋ค. ์ฐพ์๋ณด์ญ์ผ.
- ํฌํธ๋ 3000๋ฒ์ผ๋ก ์ด์ด์ฃผ๊ณ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํ
nginx/default.conf
server {
listen 3000;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri /index.html;
}
error_log /var/log/nginx/api_error.log;
access_log /var/log/nginx/api_access.log;
}
3000์ผ๋ก ์ด์ด๋จ์๊ป 3000 listen ํ๊ณ ์๋ค๊ฐ,, ์์ฒญ์ด ๋ค์ด์ค๋ฉด ์ง์ ํ root์์ index.html
์ฐพ์์ ์คํํ๋ค.
์ฌ๊ธฐ๊น์ง๊ฐ ํ๋ก ํธ ๋ ํฌ์งํ ๋ฆฌ์์ ์ค์ ํ ๋ถ๋ถ์ด๋ค. ์ด๋ ๊ฒ ๋์ปค ํ๋ธ์ ํธ์ฌํ๋ ๊ฒ ๊น์ง!! ์ปค๋ฐ์จ