2023. 9. 7. 23:04ㆍ🔴 ETC/CICD
Github Actions를 사용하기 앞서 세팅해줘야하는 내용은 이전 포스트 참고
2023.09.07 - [🔴 ETC/CICD] - [CI/CD적용기2] Docker + Github Actions으로 배포 자동화
Github Action 코드를 짜다 보니, 프로젝트 빌드하는 과정을 어떤 식으로 해야지 효율적인지 궁금해졌다.
빌드하는 부분을 총 3번의 다른 방식으로 구성해 보았고, Github Action의 걸린 시간을 살펴보았다.
첫 번째 방식, 로컬 pc에서 내가 직접 프로젝트 build -> Github Action에서 나머지 작업 자동화
Dockerfile
# nginx 이미지를 사용합니다. 뒤에 tag가 없으면 latest 를 사용합니다.
FROM nginx
# root 에 app 폴더를 생성
RUN mkdir /app
# work dir 고정
WORKDIR /app
# work dir 에 build 폴더 생성 /app/build
RUN mkdir ./build
# host pc의 현재경로의 build 폴더를 workdir 의 build 폴더로 복사
ADD ./build ./build
# nginx 의 default.conf 를 삭제
RUN rm /etc/nginx/conf.d/default.conf
# host pc 의 nginx.conf 를 아래 경로에 복사
COPY ./nginx.conf /etc/nginx/conf.d
# 80 포트 오픈
EXPOSE 80
# container 실행 시 자동으로 실행할 command. nginx 시작함
CMD ["nginx", "-g", "daemon off;"]
github-action.yml
name: WORKFLOW_FOR_DOCKER
on:
push:
branches: [ "main" ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# 1. 빌드 머신 준비
build:
runs-on: ubuntu-latest
steps:
# 2. 빌드 머신에 Repository Check Out
- uses: actions/checkout@v3
- name: Start Actions
run: echo Start Actions!
# 3. Docker Meta를 이용하여 생성할 이미지의 이름과 버전 정보 태깅
- name: Docker meta
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v1
with:
images: iDaeun/daeun-portfolio-app
tag-semver: |
{{version}}
{{major}}.{{minor}}
# 4. 빌드 머신에 Docker 빌드에 필요한 사항 준비
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
# 5. 이미지를 업로드 할 내 도커허브 로그인
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 6. 도커 이미지 빌드하고 허브로 푸쉬
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
- name: Finish Git Actions
run: |
echo Finished All Actions 🥳
echo Please Check Your Docker Hub!
on > push > branch ["main"] : main 브랜치에 코드를 푸쉬하면 Github Action이 yml 파일에 정의한 작업내용에 따라 실행된다.
먼저 프로젝트를 빌드해 놓을 뒤 main 브랜치에 강제로 test 코드를 푸쉬하여 Github Action이 시작되도록 하였다.
그 결과, 걸린 시간 : 22초
두 번째 방식, Dockerfile 내부에서 프로젝트 build 자동화 -> Github Action에서 나머지 작업 자동화
Dockerfile
## builder
FROM node:17-alpine AS builder
# work dir 고정
WORKDIR /app
COPY package-lock.json ./
COPY package.json ./
RUN npm ci
COPY . ./
RUN npm run build
# nginx 이미지를 사용합니다. 뒤에 tag가 없으면 latest 를 사용합니다.
FROM nginx
# host pc의 현재경로의 build 폴더를 workdir 의 build 폴더로 복사
COPY --from=builder /app/build /app/build
CMD ["ls", "-al"]
# nginx 의 default.conf 를 삭제
RUN rm /etc/nginx/conf.d/default.conf
# host pc 의 nginx.conf 를 아래 경로에 복사
COPY ./nginx.conf /etc/nginx/conf.d
# 80 포트 오픈
EXPOSE 80
# container 실행 시 자동으로 실행할 command. nginx 시작함
CMD ["nginx", "-g", "daemon off;"]
--from : 새로운 빌드 스테이지를 뜻한다.
'builder'라고 정해준 스테이지에서 node를 사용해 주었고, 그 아래 새로운 스테이지에서 nginx를 사용하였다.
이렇게 해서 아래와 같은 순서로 실행되도록 하였다 :
1. 첫 번째 스테이지 (builder) : node사용하여 npm으로 프로젝트 빌드 (이전에는 내가 직접 로컬 pc에서 빌드했던 과정)
2. 두 번째 스테이지 : builder 스테이지에서 빌드한 결과물을 COPY 하여 가져오고, nginx로 Docker Image 빌드
github-action.yml > 첫 번째 방식과 동일함
그 결과, 걸린 시간 : 1분 23초
세 번째 방식, Github Action에서 프로젝트 build + Docker 작업 모두 자동화
Dockerfile
# nginx 이미지를 사용합니다. 뒤에 tag가 없으면 latest 를 사용합니다.
FROM nginx
# work dir 고정
WORKDIR /app
# host pc의 현재경로의 build 폴더를 workdir 의 build 폴더로 복사
ADD ./build ./build
# nginx 의 default.conf 를 삭제
RUN rm /etc/nginx/conf.d/default.conf
# host pc 의 nginx.conf 를 아래 경로에 복사
COPY ./nginx.conf /etc/nginx/conf.d
# 80 포트 오픈
EXPOSE 80
# container 실행 시 자동으로 실행할 command. nginx 시작함
CMD ["nginx", "-g", "daemon off;"]
두 번째 방식에서 추가해 줬던 프로젝트 빌드 과정을 삭제했다.
github-action.yml
name: WORKFLOW_FOR_DOCKER
on:
push:
branches: [ "main" ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# 1. 빌드 머신 준비
build:
runs-on: ubuntu-latest
steps:
# 2. 빌드 머신에 Repository Check Out
- uses: actions/checkout@v3
- name: Start Actions
run: echo Start Actions!
## 개선 ##
- uses: actions/setup-node@v3
with:
node-version: 16.14.2
- run: npm ci
# - run : npm test (build 보다 먼저 test 실행)
- run: npm run build
- name: Log Test
run: ls -al
shell: bash
#########
# 3. Docker Meta를 이용하여 생성할 이미지의 이름과 버전 정보 태깅
- name: Docker meta
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v1
with:
images: iDaeun/daeun-portfolio-app
tag-semver: |
{{version}}
{{major}}.{{minor}}
# 4. 빌드 머신에 Docker 빌드에 필요한 사항 준비
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
# 5. 이미지를 업로드 할 내 도커허브 로그인
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 6. 도커 이미지 빌드하고 허브로 푸쉬
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
- name: Finish Git Actions
run: |
echo Finished All Actions 🥳
echo Please Check Your Docker Hub!
Github Action workflow에는 아래의 코드만 추가해 주었다 :
## 개선 ##
- uses: actions/setup-node@v3
with:
node-version: 16.14.2
- run: npm ci
# - run : npm test (build 보다 먼저 test 실행)
- run: npm run build
- name: Log Test
run: ls -al
shell: bash
#########
이는 node를 사용하여 npm install & build를 해주는 과정이다.
두 번째 방식에서는 Dockerfile에 해당 과정을 넣어주었다면, 이번에는 Github Action에 넣어준 것이다.
그 결과, 걸린 시간 : 1분
Github Actions에서 걸린 시간만 보면 첫 번째 방식이 제일 짧았지만, 이는 로컬에서 프로젝트를 빌드하는 시간을 뺀 시간이다.
그리고 나는 프로젝트 빌드하는 과정 또한 자동화하고 싶었기 때문에, 두 번째와 세 번째 방식이 내가 원하는 방향이다.
두 방식은 프로젝트 빌드를 하는 주체만 다른데, 하나는 Dockerfile에서, 다른 하나는 Github Actions에서 실행한다.
두 방식의 시간차는 약 23초로, Github Actions workflow에서 프로젝트 빌드를 해주는 게 더 빨랐다.
생각해 보면 Dockerfile에서 프로젝트 빌드를 하기 위해서는 프로젝트의 모든 소스를 COPY 한 뒤에 이를 빌드하는 방식이다.
그에 반해 Github Actions에는 소스를 COPY 할 필요 없이 바로 npm install & build를 할 수 있다.
물론 더 추가해야 하는 부분은 많지만, 프로젝트 빌드 자동화를 생각으로만 해보다가 직접 구성해 보고 개선시켜 보니 Github Actions를 이해할 수 있는 좋은 기회였다.
'🔴 ETC > CICD' 카테고리의 다른 글
[CI/CD적용기2] Docker + Github Actions으로 배포 자동화 (0) | 2023.09.07 |
---|---|
[CI/CD적용기1] React앱을 Docker Image으로 생성 후 Docker hub에 업로드 (0) | 2023.09.07 |