일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Join
- 일정관리 프로젝트
- 알고리즘
- 디자인 패턴
- LV01
- S3
- LV1
- 코테
- LV.02
- mysql
- LV02
- 프로그래머스
- Kafka
- spring boot
- 연습문제
- JPA
- docker
- Redis
- 일정관리프로젝트
- 이것이 자바다
- CI/CD
- LV03
- GIT
- LV0
- SQL
- Java
- Lv.0
- 데이터 베이스
- 포트폴리오
- CoffiesVol.02
- Today
- Total
코드 저장소.
프로젝트 배포2 - GithubAction 을 활용한 CI/CD구축하기. 본문
목차
1. 도입 / 배경
2.MobaXterm을 활용한 배포 자동화 & 운영
3.후기
1. 도입 / 배경
지난글에서는 배포를 할 기본적인 인프라를 세팅을 했고 이번에는 GithubAction을 활용해서 CI/CD를 구축을 하기로 했습니다. CI/CD를 적용을 하게 된 이유는 아래와 같습니다.
- 수동으로 서버를 올리면서 배포를 하면 작업을 하는데 있어서 시간소모가 크다.
- 작업을 하면서 운영을 하기 위해서는 빌드,테스트,배포를 자동화하는 것이 필요.
위와 같은 이유로 GithubAction을 사용해서 CI/CD를 구축을 하고자 합니다. 그래서 이번글의 목표는 아래와 같습니다.
- main 브랜치에 코드가 머지되면 자동으로 빌드/테스트/배포가 이루어지게 만드는 것
- 운영 서버에서는 실제 서비스가 무중단으로 배포/재시작되는 구조로 만들기.
구축하기 위한 도구
- MobaXterm(원격접속)
- Amazon Lightsail(운영 서버)
- GithubAction(배포 자동화)
- Docker,Jib(이미지 빌드)
이번에 구축할 CI/CD 구조도는 아래와 같습니다.
2.MobaXterm을 활용한 배포 자동화 & 운영
2-1.CI 구축하기
CI(Continuous Integration)를 구축하기 위해서는 먼저 프로젝트 루트 경로에 .github/workflows 디렉토리를 생성하고, 워크플로우 스크립트를 작성합니다.
mkdir -p .github/workflows
위와 같은 명령어를 입력을 하면 프로젝트는 .gitub디렉토리와 안에 workflows디렉토리가 만들어집니다. 아래는 CI 스크립트입니다.
name: Schedule Project CI with Compose
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
build:
runs-on: ubuntu-latest
services:
redis:
image: redis:6.2
ports:
- 6379:6379
....
전체 스크립트는 여기에서 확인이 가능합니다.
이 워크플로우의 핵심은 다음과 같습니다:
- main 브랜치에 푸시되거나 PR이 열릴 경우 CI가 자동 실행됨
- Redis, Kafka 등을 Github Actions의 서비스로 등록하여 통합 테스트 가능
- 테스트 후 Jib을 활용해 Docker 이미지 빌드까지 자동 수행
이후 main 리포지터리에 푸시를 하면 CI환경은 구축이 됩니다.
CI를 구축하는 과정에서 생긴 문제
main브랜치에 푸쉬를 했고 CI가 작동이 되었는데 아래와 같은 화면이 나왔습니다.
원인
Github Actions는 CI 환경에서 ./gradlew를 실행할 때, 내부적으로 gradle-wrapper.jar 파일을 필요로 합니다.
하지만 로컬에서 .gitignore 설정에 의해 다음 파일들이 Git에 포함되지 않았던 것이 문제였습니다.
해결 방법
다음 명령어로 누락된 wrapper 관련 파일들을 Git에 다시 추가했습니다.
git add gradlew gradlew.bat gradle/wrapper/*
git commit -m "fix: add gradle wrapper files"
git push origin main
추가후에는 정상적으로 CI가 작동이 되었습니다.
2-2.MobaXterm을 활용해서 Amazon Lightsail에 원격접속
MobaXterm을 도입한 이유
- AWS Lightsail 같은 클라우드 서버에 SSH/SCP/파일 전송/포트 포워딩을 한 번에 쓸 수 있다.
- 로컬에서 서버로 환경 파일(.env 등) 안전하게 업로드, 운영 로그 실시간 모니터링 가능하다.
MobaXterm을 사용하는 방법은 아래와 같습니다.
MobaXterm에서 Session을 누르고 SSH에서 Lightsail의 ip주소와 .pem을 넣습니다.
입력을 하고나면 아래의 화면과 같이 접속이 된것을 볼 수 있습니다.
다음으로는 Nginx와 Docker-compose에 필요한 디렉토리및 파일을 작성 및 업로드합니다.
2-3.CD 구축하기
Github Actions에서 Docker 이미지를 빌드한 후, Amazon Lightsail 서버에 자동으로 배포되는 구조를 만들었습니다.
운영 서버에서 Nginx는 리버스 프록시 및 HTTPS 인증을 담당하며, 백엔드 API 요청을 /api 경로로 전달합니다.
server {
listen 443 ssl;
server_name api.schedulemanagement.site;
location /api/ {
proxy_pass http://backend:8082/api/;
...
}
}
그리고 Nginx + Let's Encrypt를 사용해서 Https 인증서를 발급을 했습니다. 발급 방법은 아래와 같습니다.
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
Nginx 설정에 있는대로 /var/www/cerbot 디렉토리를 만듭니다.
그 후 도커 컴포즈에 있는 Nginx를 띄운후에 도커 컴포즈에 있는 설정
volumes:
- /etc/letsencrypt:/etc/letsencrypt
- /var/www/certbot:/var/www/certbot
그다음에 certbot을 이용해 인증서를 새로 발급을 합니다.
이렇게 하면 https 인증서를 발급을 받을수 있습니다.
인증에 성공하면 ./certbot/conf/live/schedulemanagement.site/fullchain.pem 생성됩니다.
성공후에는 다시 Nginx를 기동합니다.
docker restart nginx
다음 Docker Compose는 다음과 같이 구성되어 있습니다.
services:
backend:
image: well4149/schedule-management:latest
...
kafka:
image: confluentinc/cp-kafka:7.3.0
...
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
전체 CD 스크립트는 여기에서 볼 수 있습니다.
이때 도커 컴포즈를 띄우기 위해서 도커컴포즈를 설치를 한 후에 도커 컴포즈의 버전을 확인을 해봤는데 아래와 같은 문구가 나왔습니다.
docker-compose version
docker-compose version 1.29.2, build unknown
docker-py version: 5.0.3
CPython version: 3.12.3
OpenSSL version: OpenSSL 3.0.13 30 Jan 2024
이 문구는 v1(구버전) Compose만 인식되고, 최신 Docker에서는 docker compose(띄어쓰기, v2 기준) 명령이 안되기 때문에 나온 문구입니다. 그냥 구버전을 사용하면 되지 않겠냐겠지만 v2를 사용하는 이유는 아래와 같습니다.
- 최신 Docker는 v2(플러그인 방식)가 표준
- CI/CD, GitHub Actions, 공식 도큐먼트도 전부 v2 기준으로 설명이 되어있다.
- 앞으로 v1과의 호환성이 떨어지기 때문
이러한 이유로 v2를 적용을 해서 진행을 했습니다.
//기존 버전을 삭제
sudo apt remove docker-compose
//v2 설치
sudo apt update
sudo apt install docker-compose-plugin
//정상 동작 확인
docker compose version
이 다음에는 Github에 들어가서 CD를 하기 위해서 Secret을 입력을 해야합니다. 우선은 Git 리포지터리에 들어간다음에 Settings에 들어간후 Secrets and variabes로 들어갑니다. 들어가면 아래와 같은 화면이 나옵니다.
그 다음에 New Secret Repository를 누른후 도커 허브에 들어가는 아이디, 비밀번호, 라이트세일의 IP, 서버이름(mobaxterm에 작성한 이름), SSH .pem key를 입력을 하고 아래와 같이 합니다.
이렇게 세팅을 하고 프로젝트에서 CI 스크립트를 작성한 디렉토리에서 CD 스크립트를 작성후 깃에 올립니다.
name: Deploy to EC2 via SSH
on:
push:
branches:
- main # main에 merge가 되었을때 cd가 작동
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to EC2
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd ~/schedule-app
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker compose -f docker-compose.dev.yml pull
docker compose -f docker-compose.dev.yml up -d
이제 테스트를 하기 위해서 main브랜치에서 readme를 수정해서 올리면 github의 Action에서는 아래와 같이 작동을 합니다.
사진과 같이 나오면 CI/CD가 구축이 되었습니다.
3.후기
이전에 진행했던 프로젝트에서는 도커 컴포즈와 AWS CodeDeploy를 조합해서 CI/CD를 구현한 경험이 있었다. 당시에는 빌드된 이미지를 AWS 환경에 자동으로 배포하는 것만으로도 충분히 편리함을 느꼈다. 하지만 실제로 운영을 하다 보니, 서버마다 배포 방식이나 관리 포인트가 달라서, 세팅이 복잡하고 장애 시에는 수동 개입이 필요했던 부분도 있었다.
이번 프로젝트에서는 기존 방식과 다르게 Github Actions와 SSH 자동화를 활용해, 코드 푸시부터 서버 배포까지 완전 자동화되는 파이프라인을 직접 구축했다. 특히, 서버에 직접 접속해서 명령어를 입력하는 단계조차 사라졌고, 애플리케이션 배포의 반복적인 실수를 크게 줄일 수 있었다.
과거에는 CodeDeploy를 통한 배포 자동화가 한계였지만, 이번에는 docker compose 버전 통일, Nginx 인증서, 환경 변수 관리 등 실전에서 더 자주 마주치는 문제까지 직접 다뤄본 덕분에 단순히 ‘자동화’만 하는 게 아니라 실제로 장애를 진단·해결하고, 자동화 파이프라인의 안정성을 높이는 노하우도 키울 수 있었다.
이번 경험을 통해 여러 가지 배포 도구와 방식의 장단점을 비교할 수 있게 되었고, 자동화는 도구 자체보다, “얼마나 일관성 있게 운영/관리할 수 있느냐”가 더 중요하다는 걸 확실히 느꼈다. 다음에는 여러 환경(EC2, Lightsail, 컨테이너 서비스 등)에 맞는 배포 자동화 경험을 더 확장해보고 싶다.
추후에는
- 모니터링(Promethus,Granfana,Loki)를 적용해서 모니터링하기.
- 배포 후 슬랙에 알림 자동화
- Blue-Green 배포
를 적용을 해볼 예정입니다.
'포폴 > 일정관리앱' 카테고리의 다른 글
Spring 서비스의 운영 모니터링 환경 구축기1: Prometheus, Grafana, Loki, Kafka/Redis Exporter (0) | 2025.06.17 |
---|---|
Kafka + Redis + MySQL 환경을 Testcontainers로 통합 테스트하기 (0) | 2025.06.10 |
Jib을 활용한 Docker 이미지 자동화 빌드 경험기 (0) | 2025.05.27 |
일정알림기능4-아웃 박스 패턴을 적용하기(트랜잭션 일관성과 장애 복원력 강화) (0) | 2025.05.24 |
프로젝트 배포1 - 수동 인프라 세팅 (0) | 2025.05.17 |