CI/CD, Docker 에 대해서 말할거면 기본으로 알아야 할 내용들

말하는 감자·2025년 5월 14일

내일배움캠프

목록 보기
58/73
post-thumbnail

CI/CD

왜 CI/CD가 중요하게 되었나??

과거에는 폭포수 개발 방식처럼 한 번에 대규모로 개발하고 배포하는 방식이 주류였지만,
최근에는 애자일 개발 방식의 도입으로 점진적인 지속적인 통합(CI)지속적인 배포(CD) 를 지향하게 되었음<<






https://www.redhat.com/ko/topics/devops/what-is-ci-cd

개념

CI/CD는 코드 작성 → 테스트 → 빌드 → 배포 전 과정을 자동화하여
더 빠르고 안정적으로 서비스를 제공하기 위한 개발 문화이자 자동화 파이프라인이다.

CI/CD는 💡 지속적 통합(Continuous Integration) 및 지속적 💡 제공/배포(Continuous Delivery/Deployment)를 의미하며, 소프트웨어 개발 라이프사이클을 간소화하고 가속화하는 것을 목표로 한다..

지속적 통합(CI)은 코드 변경 사항을 공유 소스 코드 리포지토리에 자동으로 자주 통합하는 사례를 나타냄.

지속적 제공 및/또는 배포(CD)는 코드 변경 사항의 통합, 테스트, 제공을 나타내는 프로세스로, 두 가지 부분으로 구성된다.
지속적 제공에는 자동 프로덕션 배포 기능이 없는 반면, 지속적 배포는 업데이트를 프로덕션 환경에 자동으로 릴리스할 숭 ㅣㅅ음.

이렇게 연결된 두 사례를 일반적으로 'CI/CD 파이프라인' 이라 부르며, 개발 팀과 운영 팀이 DevOps 또는 SRE(사이트 신뢰성 엔지니어링)를 통해 애자일 방식으로 협력하여 이를 지원한다.



💡 CI (Continuous Integration) — 지속적 통합

  • 여러 개발자의 코드를 통합할 때 자동으로 테스트를 수행하여 오류를 사전에 방지함.

⚙️ 자동화 예시

  • git push → GitHub Actions가 자동으로 ./gradlew test 실행
  • PR 생성 → ESLint, Test 통과 여부 확인
  • PR Merge 막기 → 테스트 실패 시
  • 예: GitHub Actions에서 Pull Request 발생 시 gradle test 자동 실행



💡 CD (Continuous Deployment) — 지속적 배포

  • 테스트를 통과한 코드가 자동으로 배포 서버에 반영됨.
    CI를 통과한 코드를 자동으로 빌드, 패키징, 배포까지 진행하여 사용자가 즉시 기능을 사용할 수 있게 하는 프로세스

⚙️ 자동화 예시

  • main 브랜치로 머지되면 → ./gradlew build → Docker 이미지 생성 → Cloudtype에 배포
  • 배포 전 DB 마이그레이션 자동 수행
  • 슬랙이나 이메일로 배포 알림 전송
  • 예: main 브랜치에 병합되면 자동으로 jar 파일을 빌드하여 Cloudtype, AWS 등에 배포함.





♾️ CI/CD 흐름 (GitHub Actions + Docker + Cloudtype)

  1. feature/ 브랜치에서 기능 개발 및 테스트 코드 작성
  2. Pull Request 생성 시 GitHub Actions가 gradle test 자동 수행 (CI)
  3. 테스트 실패 시 PR 업데이트 / 성공 시 코드 리뷰 및 승인 대기
  4. PR 승인 후 main 브랜치로 병합
  5. 병합되면 Docker 이미지 빌드 및 클라우드 서버에 자동 배포 (CD)






🐳 Docker란?

https://velog.io/@justlikesh/Docker%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC

전통적인 가상화 (VM)

구조: Host OSHypervisorGuest OSApp
특징:
각각의 애플리케이션이 자기만의 OS(Guest OS)를 가짐
자원(메모리, 디스크 등) 소비가 큼
무겁고 부팅도 느림

컨테이너 기반 가상화 (Docker)

구조: Host OSDocker 엔진App + 라이브러리
특징:

  • Host OS의 커널을 공유함 (OS 중복 X)
  • 애플리케이션 실행에 필요한 바이너리와 라이브러리만 포함
  • 가볍고 빠름

"애플리케이션 + 실행환경"을 하나의 단위로 묶어주는 컨테이너 기술.

Docker는 애플리케이션을 컨테이너라는 독립된 공간에서 실행할 수 있게 해주는 플랫폼임.
도커 덕분에 앱의 실행 환경을 고정해서, 어디서 실행해도 똑같이 동작하도록 보장함.



🍱 도커는 도시락

  • 애플리케이션을 도시락 반찬이라고 해보자.
  • 도시락통(컨테이너) 안에 반찬 + 밥 + 젓가락(라이브러리, 설정 파일 등)을 함께 포장해서, 어디서든 먹을 수 있도록 만드는 것.
  • 이 도시락을 회사든, 친구 집이든, 배달가게든 "어디서나 똑같이" 먹을 수 있음 → 실행환경 통일





왜쓰냐?

도커는 개발과 배포 과정에서 흔히 겪는 여러 문제를 효과적으로 해결해준다.

예를 들어, "내 PC에선 잘 되는데?" 같은 상황은 도커 컨테이너가 항상 동일한 환경에서 실행되기 때문에 방지할 수 있다.
서버마다 환경 설정이 복잡한 경우에도 도커 이미지를 통해 실행 환경을 미리 정의할 수 있어 설정을 단순화할 수 있다.
배포를 자동화하고 싶을 때도 도커는 CI/CD 파이프라인과 잘 어울려 자동화된 빌드와 배포에 적합하다.
또한 테스트 환경을 서로 격리하고 싶을 때는 여러 개의 컨테이너를 동시에 실행시켜 독립된 테스트 환경을 손쉽게 구성할 수 있다.


Docker의 기본 개념

용어설명비유
이미지컨테이너를 만들기 위한 “설계도”도시락 레시피 (붕어빵 틀)
컨테이너이미지를 실행한 실체도시락 실물 (만들어진 붕어빵)
Dockerfile이미지를 만들기 위한 텍스트 파일레시피 카드 (붕어빵 틀 만드는 방법 설명서)
Docker Hub이미지를 공유하는 저장소도시락 마켓 (붕어빵 틀 판매하는 상점- 여러개이씅ㅁ)
볼륨(Volume)컨테이너와 실제 PC 사이의 파일 공유 영역도시락에 붙은 외부 주머니
네트워크(Network)컨테이너끼리 연결하는 가상의 통신망같은 회식 테이블에 앉은 도시락들

도커를 사용하면 앱의 독립성, 확장성, 이동성이 크게 향상됨.

🔄 전체 흐름: "이미지 → 컨테이너 실행" 과정



1. Dockerfile

개발자가 작성하는 "컨테이너 만드는 레시피"

  • 어떤 OS를 기반으로 할지
  • 어떤 파일을 복사할지
  • 어떤 명령어를 실행할지
  • 이 정보들을 단계별로 명시하는 설정 파일

🍱 비유: 도시락 레시피 카드



2. docker build → 이미지(Image) 생성

Dockerfile을 기반으로 하나의 이미지 파일을 만든다.

docker build -t my-app .

커ㅗ멘드 뜻 : 현재 디렉토리(.)에 있는 Dockerfile을 기반으로
my-app이라는 이름(tag)을 가진 Docker 이미지 하나를 만든다.
(현재 디렉토리에 있는 Dockerfile을 기반으로, my-app이라는 이름을 가진 이미지를 만들겠다)

  • 도커는 각 명령어를 계층적으로 Layer로 쌓는다
  • 한 번 만든 레이어는 재사용 가능 (캐싱)
  • 결과적으로 my-app:latest 같은 이미지가 만들어짐

🍱 비유: 레시피대로 도시락을 한번 만들어보고 냉동보관해둠



3. docker run → 컨테이너(Container) 생성 + 실행

이미지로부터 실체를 띄우는 단계.
컨테이너는 이미지의 실행 중인 인스턴스다.

docker run -d -p 8080:8080 my-app

커멘드 뜻 : my-app이라는 이름의 이미지로부터 컨테이너를 하나 생성하고,
그 컨테이너를 백그라운드(-d)로 실행하며,
외부(호스트)의 8080 포트를 컨테이너 내부의 8080 포트에 연결한다.
(my-app 이미지를 컨테이너로 실행하겠다. 외부 포트 8080을 내부 포트 8080에 연결해서 접속 가능하게 하ㄹ게)

  • 이미지 기반으로 격리된 공간에서 앱을 실행
  • 포트, 볼륨, 환경 변수 등을 설정 가능

🍱 비유: 냉동된 도시락을 꺼내 전자레인지에 돌려 먹는 것 (붕어빵틀로 붕어빵 만들어서 머금)



4. 컨테이너 내부에서 앱 실행

ENTRYPOINT, CMD 등에 정의된 명령어에 따라 앱이 실행된다.
예: java -jar app.jar
Spring Boot, Node.js, Python 서버 등이 여기서 구동됨



5. 사용자는 앱에 접속

외부 포트(-p 8080:8080)로 접속 → 컨테이너 내부 앱에 연결됨
브라우저에서 localhost:8080 접속
컨테이너는 격리되어 있지만, 포트 연결을 통해 외부와 통신함

🍱 비유: 도시락통 안의 밥을 꺼내 먹으려면 뚜껑 열고 수저(포트) 꽂아야 함







은아니고
볼륨에 대해서 좀 적으려고하는데 생각보다 양이좀있어서 내일 TIL으로 ㅎㅎ

profile
대충 데굴데굴 굴러가는 개발?자

0개의 댓글