군만두의 IT 개발 일지

패스트캠퍼스 8기 백엔드 개발 부트캠프 멘토님 특강 - GitHub Actions와 CI/CD 개념 및 실습 본문

개발일지/패스트캠퍼스

패스트캠퍼스 8기 백엔드 개발 부트캠프 멘토님 특강 - GitHub Actions와 CI/CD 개념 및 실습

mandus 2024. 4. 8. 21:33

목차

    📅 진행일: 2024년 4월 8일

    ⭐ 요약


    • 패스트캠퍼스 백엔드 개발 부트캠프 8기의 김멘토님 특강으로, CI/CD 개념과 GitHub Actions 실습을 진행했다.
    • CI/CD가 필요한 이유를 실무 시나리오를 통해 이해하고, Continuous Delivery와 Continuous Deployment의 차이를 학습했다.
    • application.yml을 환경별로 분리하는 방법과 JUnit5를 활용한 테스트 코드 작성을 실습했다.

    ⭐ 특강 개요


    멘토님은 부트캠프 주강사 및 다수의 특강 연사 경험을 보유한 개발자이다. 이번 특강은 총 2회로 구성되며, 1회차인 이번 세션에서는 CI/CD 개념과 환경 설정 실습을 다루었다. 2회차인 6월 10일에는 AWS EC2 인스턴스 생성 및 실제 CI/CD 구축을 진행할 예정이다.

    회차 날짜 주요 내용
    1회차 2024.04.08 CI/CD 개념, GitHub Actions 소개, application.yml 분리, 테스트 코드 작성
    2회차 2024.06.10 AWS EC2 인스턴스 생성, GitHub Actions 기반 CI/CD 실제 구축

    ⭐ 학습 내용


    1. CI/CD란 무엇인가

    1-1. CI/CD가 필요한 이유: 효율성과 생산성

     

    멘토님은 CI/CD의 필요성을 단순한 기술 관점이 아닌 회사 입장의 효율성과 생산성으로 설명하셨다. 개발자가 ChatGPT를 쓰는 이유처럼, 반복적인 배포 과정을 자동화하면 시간을 절약하고 인풋 대비 아웃풋을 높일 수 있다.

     

    "여러분들이 취직하실 때나 회사 입장을 생각하셔야 돼요. 조직 입장. 단순한 개발자 입장으로만 보시면 안 됩니다."

     

    1-2. 수동 배포의 문제점 - 시나리오로 이해하기

     

    CI/CD 없이 수동으로 배포할 때의 흐름과 문제점은 아래와 같다.

    단계 작업 문제점
    1 기능 개발 후 GitHub에 push 팀원이 늘어날수록 이 과정이 반복되며, 빌드 실패나 실행 에러 발생 시 서비스가 중단됨. 특히 사용자가 접속 중에 서버가 다운되면 데이터 손실로 이어질 수 있음
    2 서버에서 git pull로 최신 코드 받아오기
    3 빌드 (gradle build → .jar 파일 생성)
    4 기존 실행 중인 서비스 중지
    5 새 .jar 파일 실행 및 테스트

    실무에서는 최소한 테스트 서버프로덕션 서버 두 개를 운용한다. 각 서버마다 이 과정을 반복해야 하며, 빌드 실패나 실행 에러가 발생하면 서비스 중단으로 이어지는 크리티컬한 이슈가 된다. 이를 방지하는 기술이 바로 무중단 배포이며, CI/CD가 이 과정을 자동화해준다.

    2. CI와 CD의 개념

    2-1. CI: Continuous Integration (지속적 통합)

     

    코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 레포지토리에 통합되는 과정이다. 핵심은 레포지토리의 정합성을 지키는 것이다.

     

    예를 들어 개발자 A와 B가 각각 PR을 올렸을 때, GitHub Actions(CI 시스템)가 자동으로 빌드 테스트를 수행한다. 테스트를 통과한 커밋만 메인 레포지토리에 병합되고, 실패한 커밋은 병합이 차단된다. 이렇게 하면 레포지토리를 pull한 다른 개발자들이 빌드 오류를 겪는 상황을 예방할 수 있다.

     

    2-2. CD: Continuous Delivery vs Continuous Deployment

     

    구분 Continuous Delivery (지속적 전달) Continuous Deployment (지속적 배포)
    배포 방식 스테이징까지 자동, 프로덕션은 수동 배포 프로덕션까지 자동 배포
    사용 상황 배포 대상 환경이 여러 고객사로 달라 자동화가 불가능할 때 배포 환경이 고정되어 자동화가 가능할 때
    개발자 리소스 상대적으로 적음 초기 설정 비용이 크지만 장기적으로 효율적
    선호도 환경 제약이 있을 때 선택 일반적으로 더 선호됨

    3. CI/CD 툴: GitHub Actions vs Jenkins

    대표적인 CI/CD 툴로는 GitHub ActionsJenkins가 있다. 이번 특강에서는 GitHub Actions를 사용한다.

     

    특징 적합한 상황
    GitHub Actions 러닝 커브가 낮고 설정이 간단함. GitHub과 네이티브 연동 비교적 소규모 서비스, 빠르게 CI/CD 구축할 때
    Jenkins GitHub Actions보다 러닝 커브가 높음. 플러그인 생태계 풍부 대규모 엔터프라이즈 환경, 복잡한 파이프라인이 필요할 때

    4. application.yml 환경별 분리 실습

    실무에서는 개발(dev) 환경과 운영(prod) 환경의 설정이 다르기 때문에 application.yml을 환경별로 분리하는 것이 일반적이다. 실습에서는 application-dev.ymlapplication-prod.yml로 나누어 서버 포트 등의 설정을 각각 다르게 지정했다.

     

    Spring Boot에서 특정 프로파일로 애플리케이션을 실행하려면 아래와 같이 설정한다.

    # application.yml
    spring:
      profiles:
        active: dev  # dev 프로파일로 실행

     

    트러블슈팅 - IntelliJ Gradle 빌드 오류: 일부 수강생에게 프로파일이 제대로 읽히지 않는 문제가 발생했다. 원인은 Gradle 빌드 설정이었으며, IntelliJ 설정에서 아래와 같이 변경하면 해결된다.

    # 해결 방법
    # IntelliJ IDEA 설정 → 빌드, 실행, 배포 → 빌드 도구 → Gradle
    # "다음을 실행하여 빌드 및 테스트 실행" 옵션을
    # Gradle → IntelliJ IDEA 로 변경

     

    5. 테스트 코드 작성 실습

    JUnit5와 AssertJ를 사용하여 간단한 테스트 코드를 작성했다. 테스트의 핵심은 assertEquals(같니?)assertNotEquals(같지 않니?)로 값을 검증하는 것이다.

    @SpringBootTest
    @ActiveProfiles("dev")  // dev 프로파일로 테스트 실행
    class ServiceTest {
    
        @Autowired
        private TestService testService;
    
        @Value("${server.port}")
        private String serverPort;
    
        // 성공 케이스: dev 환경의 포트(3444)와 같니?
        @Test
        void checkPortSuccess() {
            assertEquals("3444", serverPort);
        }
    
        // 실패 케이스: 8080과 같지 않니?
        @Test
        void checkPortFail() {
            assertNotEquals("8080", serverPort);
        }
    
        // 문자열 반환 메서드 테스트
        @Test
        void testString() {
            assertEquals("develop server3444", testService.getString());
        }
    }

     

    테스트 실행 시 초록불이 나오면 모든 테스트가 통과된 것이다. 테스트가 실패하면 기댓값과 실젯값의 차이를 에러 메시지로 확인할 수 있다.

    6. Spring 레이어 구조 정리

    멘토님은 스프링을 학습하면서 단순히 개발만 할 것이 아니라 각 레이어의 역할과 동작 원리를 이해해야 면접에서 설명할 수 있다고 강조하셨다.

    레이어 역할 대표 어노테이션
    Controller 데이터의 입출력 담당. 클라이언트 요청을 받아 Service에 전달하고 결과를 반환 @Controller, @RestController
    Service 비즈니스 로직 처리 @Service
    Repository DB와 연동하여 데이터를 조회하고 저장 @Repository

     

    "개발만 하시면 안 돼요. @Service 어노테이션이 뭔지, @Autowired가 스프링에서 어떻게 동작하는지, 의존성 주입을 왜 했는지 설명할 수 있어야 합니다. 이 정도면 스프링 50%는 했다고 봐요."

     

    ⭐ 정리


    주제 요약
    CI/CD 필요성 수동 배포의 반복 작업을 자동화하여 효율성과 생산성을 높임
    CI PR 올릴 때 자동으로 빌드 및 테스트. 실패 시 병합 차단으로 레포지토리 정합성 유지
    CD - Delivery 스테이징까지 자동, 프로덕션은 수동. 배포 환경이 다양할 때 사용
    CD - Deployment 프로덕션까지 자동 배포. 일반적으로 더 선호됨
    application.yml 분리 dev/prod 환경별로 분리하여 환경에 맞는 설정 적용
    테스트 코드 assertEquals/assertNotEquals로 값 검증. 초록불 = 통과

    ⭐ 후기


    • CI/CD를 단순히 "자동 배포"라고만 알고 있었는데, 실무 시나리오를 통해 왜 필요한지 구체적으로 이해할 수 있었다. 배포 과정에서 빌드 실패가 서비스 중단으로 이어진다는 것, 그리고 그것이 데이터 손실까지 발생시킬 수 있다는 점이 인상적이었다.
    • Continuous Delivery와 Continuous Deployment가 같은 CD로 표기되지만 전혀 다른 개념임을 처음 알았다. 실무에서 어떤 상황에 어떤 방식을 선택하는지 이해하게 되었다.
    • 멘토님의 "개발만 하시면 안 돼요"라는 말씀이 가장 기억에 남는다. 어노테이션을 쓰면서도 왜 쓰는지, 스프링이 내부적으로 어떻게 동작하는지 이해하는 것이 중요하다는 것을 다시 한번 깨달았다.

     

    이 글은 패스트캠퍼스백엔드 개발 캠프에서 공부한 내용을 작성한 것입니다.

     

    Comments