개발일기
Spring Github Action CI/CD docker-compose 자동화 배포 구축-완- 본문
Spring Github Action CI/CD docker-compose 자동화 배포 구축-완-
한둥둥 2024. 7. 1. 15:43본격적인 Github Action CI/CD세팅 전에 CI/CD란 무엇인지 꼭 해야하는지 알아보자!
우선적으로, CI/CD란?
CI/CD는 Continuous Integration(CI) 와 Continuous Delivery/Delpoyment(CD) 통합해서 부르는 용어이다.
CI/CD는 개발 과정에서 필요한 빌드, 테스트, 배포 등의 과정을 자동화 해준다. CI/CD 자동화를 통해서 개발자들은 코드를 자동으로 테스트하고 배포할 수 있으며, 효율적인 작업이 가능해진다.
왜 CI/CD를 해야하는가?
우선적으로, 위에 내용만 보았을 때, CI/CD는 무조건 해야한다고 판단한다. 물론 수동으로 서버를 배포하는 방법도 있겠지만, 앞으로 서비스를 계속해서 운영한다면 코드를 수정하고 이를 계속해서 배포해야하는데, ci/cd를 반드시 해야한다고 생각이 들었다.
번외로 매번 EC2 서버에 코드 수정 후 들어가서 배포하는 방법이 진짜 많은 시간이 생각보다 소요가 되었고 때문에 CI/CD를 구축하는 결정을 하게 되었다.
Jenkins VS Github Action ?
둘 중 어떤 것을 써야할 지 고민하게 되었고 각각의 장단점을 비교해보았다.
Jenkins 특징들
1. 관련 문서나 자료들이 정말 많았습니다.
2. 환경 호환성을 위해 Docker image에서 동작시켜야 한다.
3. 다양한 플러그인이 있어서 다양한 설정이 가능함.
4. Github 이벤트에 준수하지 않는 빌드 중심으로 한다.
5. CI/CD 구성하는게 어려운 편
GithubAction들
1. 관련 문서가 상대적으로, Jenkins에 비하면 많이 없는 편
2. 손쉽게 Github Action을 통해서 CI/CD를 구성할 수 있다.
둘 중 어떤걸 사용할지 고민하다가 GithubAction으로 결정하였다.
why?
저는 하나의 서버를 사용할 것이며 이를 통해서 Github Action을 작성할 때, 한 대의 서버에 대해서만 도커를 사용하여 자동화 배포를 진행하며 또한 Github에 좀 더 잘 동작하며 한 곳에서 관리한다는 느낌을 받았기에 GithubAction을 사용하였다.
추가적인 이유에 자동화 배포를 할 때, 많은 플러그인과 기능을 사용하지 않기도 하며 이를 어느정도 GithubAction에서 커버 할 수 있지 않을까라는 생각으로 GithubAction 으로 진행
Dockerfile
services: #이 항목 밑에 실행하려는 컨테이너들을 정의
server:
container_name: back
image: hanseu9839/back:latest
expose:
- 8080
ports:
- 8080:8080
front:
container_name: front
image: hanseu9839/front:latest
expose:
- 3000
nginx:
container_name: nginx
image: nginx:latest
restart: unless-stopped
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
ports:
- 80:80
- 443:443
depends_on:
- server
- front
certbot:
image: certbot/certbot
restart: unless-stopped
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
mysql: # 서비스 명
image: mysql/mysql-server:8.0.23 #사용할 이미지
container_name: capo # 컨테이너 이름 설정
ports :
- "3306:3306" # 접근 포트 설정 ( 컨테이너 외부:컨테이너 내부)
restart: always
environment: # -e 옵션
MYSQL_DATABASE: # 데이터 베이스 이름
MYSQL_ROOT_HOST: # MYSQL HOST
MYSQL_ROOT_PASSWORD: # MYSQL 패스워드 설정 옵션
TZ: "Asia/Seoul"
github action 파일
name: Java CI/CD pipeline
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
java-package: 'jdk' # JDK 패키지 설치
- name: make application-dev.yml
run: |
cd ./src/main/resources
touch ./application-dev.yml
echo "${{ secrets.APPLICATION_DEV }}" > ./application-dev.yml
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle # Gradle 설정
run: ./gradlew build
# Docker 이미지 빌드
- name: Docker build & Push
run: |
docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_PASSWORD }}
docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/back .
docker push ${{ secrets.DOCKERHUB_USERNAME }}/back
# AWS 자격증명 부분 추가
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
- name: Deploy to server
uses: appleboy/ssh-action@master
id: deploy
env:
APP: "back"
COMPOSE: "/home/capo_project/docker-compose.yml"
with:
host: ${{ secrets.EC2_HOST }} # EC2_HOST 키
username: ubuntu
key: ${{ secrets.EC2_PRIVATE_KEY }} # PRIVATE_KEY
port: 22
envs: COMPOSE
script: |
sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
sudo docker rm -f $(docker ps -qa)
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/back
sudo docker-compose -f $COMPOSE up -d
해당 부분은 ssl인증 및 mysql도 image로 설정하기 위한 도커 파일이다.
server:
container_name: back
image: hanseu9839/back:latest
expose:
- 8080
ports:
- 8080:8080
front:
container_name: front
image: hanseu9839/front:latest
expose:
- 3000
해당 부분만 작성하면 된다.
** 여기서 주의할 점은 image로 설정해야한다는 것이다.
왜냐면 github action에서 docker image를 hub에 업로드하면 context를 통해서 path를 ec2내부에서 인식해서 잡을 수 없기 때문에 이미지로 바꿔서 띄워 주어야 한다.
# AWS 자격증명 부분 추가
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
aws 자격증명을 해주는 부분이다.
AWS에서 AWS_ACESS_KEY_ID 와 AWS_SECRET_ACCESS_KEY는 AWS IAM에서 IAM생성 후 발급 받을 수 있다.
만들면서 느낀 점은 포토폴리오로 만들기 위해서 github repository를 public으로 제공해야하기 때문에 환경 변수를 통해서 제공하였다.
또한 github자체에서 치명적인 키 여부는 github repository에 push하지 못하도록 만들어져있다.
위에 코드 처럼 작성했을 때, 너무 코드가 더럽고 제대로 동작하지 않았다.. 그래서 다시 리팩토링을 한 결과
이런식으로 작성해주게 되었으며
- name: make application-dev.yml
run: |
cd ./src/main/resources
touch ./application-dev.yml
echo "${{ secrets.APPLICATION_DEV }}" > ./application-dev.yml
해당 부분을 추가해주었고 환경변수에 관한 부분을 다 삭제해버렸다. dev에 해당하는 .yml을 정상적으로 읽어 프로젝트를 빈 설정 할 수 있게 되었다.
- name: Deploy to server
uses: appleboy/ssh-action@master
id: deploy
env:
APP: "back"
COMPOSE: "/home/capo_project/docker-compose.yml"
with:
host: ${{ secrets.EC2_HOST }} # EC2_HOST 키
username: ubuntu
key: ${{ secrets.EC2_PRIVATE_KEY }} # PRIVATE_KEY
port: 22
envs: COMPOSE
script: |
sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
sudo docker rm -f $(docker ps -qa)
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/back
sudo docker-compose -f $COMPOSE up -d
ssh 접근을 해주는 부분이다.
ssh 접근하여 실질적으로 docker 연결하는 형식이다.
출처:)
Jenkins vs Github Action 어떤걸 쓰는게 좋을까?
개요 > IT-Hermes 프로젝트 개발 과정에서, 배포를 업데이트 하는 과정에 너무 오랜시간이 걸렸습니다. 특히 이번 프로젝트의 경우 주요 서버들이 너무 많았습니다. 프로젝트에 필요한 서버는 다음
velog.io
CI/CD란? - 테스트, 배포 자동화
CI/CD CI/CD는 Continuous Integration(CI)와 Continuous Delivery/Deployment(CD)를 통합해서 부르는 용어다. CI/CD는 개발 과정에서 필요한 빌드, 테스트, 배포 등의 과정을 자동화한다. CI/CD 자동화를 통해서 개발자
khys.tistory.com
https://velog.io/@beardfriend/CICD%EA%B0%80-%ED%95%84%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0
'photocard backend server 개발일기' 카테고리의 다른 글
Web Socket 파헤쳐보기 (9) | 2024.07.13 |
---|---|
React + Spring Oauth2 구글, 카카오 로그인 (0) | 2024.07.03 |
Docker-compose Next.js spring-boot 배포하기 (0) | 2024.06.09 |
docker spring build 하여 배포하기 (1) | 2024.06.06 |
[Re] docker-compose를 통한 ssl 인증 (2) | 2024.06.06 |