반응형
Notice
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 버전관리
- 컴퓨터비전
- 데이터구조
- 인공지능
- 자료구조
- 파이썬
- 웹개발
- 클라우드컴퓨팅
- 네트워크
- 데이터과학
- 컴퓨터공학
- 자바스크립트
- 소프트웨어
- 보안
- springboot
- 데이터베이스
- Yes
- 컴퓨터과학
- 알고리즘
- 디자인패턴
- 사이버보안
- 프로그래밍
- 프로그래밍언어
- I'm Sorry
- 소프트웨어공학
- 머신러닝
- 딥러닝
- 네트워크보안
- 빅데이터
- 데이터분석
Archives
- Today
- Total
스택큐힙리스트
자바 스프링 개발 시작하기 - 14일차 배포 자동화 & 운영 본문
반응형
왜 지금 ‘배포 자동화’에 집중해야 할까?
서비스가 성장할수록 “서버 잠깐 내릴게요!”라는 말은 곧 사용자 이탈로 직결됩니다. 배포가 초 단위로 끝나더라도, 그 사이에 접속한 유저에게는 502 Bad Gateway가 찍히죠. 이번 14일차에서는 Docker + GitHub Actions + AWS EC2를 이용해 코드 push → 빌드 → 테스트 → 배포 → 헬스체크까지 전 과정을 자동화하고, 트래픽 손실 없는 무중단 배포(블루-그린 패턴)를 구축합니다.
1️⃣ Dockerfile: 가볍고 안전하게 빌드하기
# 1단계: 컴파일
FROM eclipse-temurin:21 as builder
WORKDIR /app
COPY . .
RUN ./mvnw -Dmaven.test.skip=true package
# 2단계: 실행 전용 이미지
FROM eclipse-temurin:21-jre-alpine
ARG JAR_FILE=/*.jar
COPY --from=builder /app/target/${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:8080/actuator/health | grep UP || exit 1
- 멀티-스테이지 빌드로 이미지 용량을 최소화.
- HEALTHCHECK를 포함해 컨테이너 내부에서 애플리케이션 상태를 주기적으로 확인.
2️⃣ GitHub Actions Workflow: ‘push = 배포’ 파이프라인
name: CI/CD
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# 1) 테스트
- name: Run Unit Tests
run: ./mvnw test
# 2) Docker 이미지 빌드 & 푸시
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build & Push
run: |
docker build -t ${{ secrets.DOCKER_USERNAME }}/spring-app:${{ github.sha }} .
docker push ${{ secrets.DOCKER_USERNAME }}/spring-app:${{ github.sha }}
# 3) EC2에 SSH 접속하여 신규 컨테이너 배포
- name: Deploy to EC2
uses: appleboy/ssh-action@v1.0.4
with:
host: ${{ secrets.EC2_HOST }}
username: ec2-user
key: ${{ secrets.EC2_KEY }}
script: |
./deploy.sh ${{ github.sha }}
- 빌드 성공 후 바로 deploy.sh를 호출해 EC2 내에서 블루-그린 스위칭을 수행합니다.
3️⃣ 무중단 배포 스크립트(deploy.sh) 핵심 로직
#!/usr/bin/env bash
IMAGE_TAG=$1
BLUE_PORT=8081
GREEN_PORT=8082
# ① 현재 서비스 중인 포트 조회
ACTIVE_PORT=$(curl -s http://localhost/port)
if [ "$ACTIVE_PORT" = "$BLUE_PORT" ]; then
IDLE_PORT=$GREEN_PORT
COLOR="GREEN"
else
IDLE_PORT=$BLUE_PORT
COLOR="BLUE"
fi
echo "▶ 새 버전을 $COLOR($IDLE_PORT) 환경에 배포"
# ② 새 컨테이너 실행
docker pull myrepo/spring-app:${IMAGE_TAG}
docker rm -f app-${COLOR} || true
docker run -d --name app-${COLOR} -p ${IDLE_PORT}:8080 myrepo/spring-app:${IMAGE_TAG}
# ③ 헬스체크 (30초 내 200 OK 확인)
for i in {1..30}; do
STATUS=$(curl -s http://localhost:${IDLE_PORT}/actuator/health | grep UP)
if [ -n "$STATUS" ]; then
echo "Health check passed"
break
fi
echo "Waiting for app… ($i/30)"
sleep 1
done
# ④ Nginx 업스트림 스위치 & 설정 리로드
sudo sed -i "s/port=.*/port=${IDLE_PORT}/" /etc/nginx/conf.d/upstream.conf
sudo nginx -s reload
echo "✔ 트래픽 전환 완료. $IDLE_PORT 가 동작 중"
# ⑤ 기존 컨테이너 정리
docker rm -f app-${ACTIVE_PORT} || true
- 현재 서비스 포트와 대기 포트를 번갈아 가며 사용해 끊김 없이 배포.
- 헬스체크 실패 시 트래픽 전환을 중단해 장애를 예방.
4️⃣ 스프링 Boot Actuator로 헬스 체크 강화하기
# application.yml
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
probes:
enabled: true
group:
readiness:
include: diskSpace, ping
- readiness 그룹을 활용해 디스크 용량, DB 연결 등도 함께 검증.
- 컨테이너 재시작 시 쿠버네티스·ECS로 옮겨가도 그대로 재사용 가능.
5️⃣ 운영 팁
- 로그 롤링: docker logs 대신 Filebeat + ELK를 붙여 장기간 보존.
- 보안: AWS Systems Manager Session Manager로 SSH Key 없이 접속, 액세스 로그 남기기.
- 비용 절감: Auto-Scaling Group + Spot Instance로 유휴 시간대 비용 40 % 절약.
✨ 마무리
오늘은 “push 한 번으로 끝나는” 무중단 배포 파이프라인을 완성했습니다. 다음 배포부터는 콘솔 대신 커밋 메시지로 배포 기록이 남고, 장애 없는 업데이트가 가능해집니다. 내일은 모니터링을 곁들인 로그 & 메트릭 수집으로 더 탄탄한 운영 환경을 만들어 봅시다!
반응형
'개발' 카테고리의 다른 글
Proxy 패턴: ‘대리’로 구현하는 로깅·보안·캐싱 마법 (0) | 2025.07.21 |
---|---|
AWS CodePipeline & CodeDeploy vs GitHub Actions 비교 분석 (1) | 2025.07.21 |
Asciidoc & Spring REST Docs로 API 문서 자동화 (0) | 2025.07.20 |
JDD(주둥아리 주도 개발) (2) | 2025.07.20 |
DD 패밀리 완전 정복 (1) | 2025.07.20 |
Comments