🐋 목차
🩵 학습 목표
- CI/CD 사용 이유를 이해합니다.
- Docker 사용 이유를 이해합니다.
- 윈도우11 이나 MacOS에서 도커 실행 환경을 구성합니다.
- 간단한 Container 서비스 구현 실습을 통해 앱을 실행합니다.
1. CI/CD란 무엇인가?
CI/CD
- Continuous Integration(지속적 통합)과 Continuous Delivery 또는 Continuous Deployment(지속적 제공 또는 지속적 배포)의 약자
- 소프트웨어 개발에서 개발 → 테스트 → 배포의 과정을 자동화하여 더 빠르고 안정적으로 서비스를 제공하기 위한 DevOps의 핵심 개념
CI (지속적 통합, Continuous Integration)
- 개발자들이 작은 단위로 자주 코드를 통합(merge)하고, 그때마다 자동으로 빌드 및 테스트하는 프로세스
- 목적
- 코드 통합 시 충돌 방지
- 자동화된 테스트를 통해 버그를 초기에 발견
- 개발자 간 협업 효율 증대
- 예시
- 개발자가 GitHub에 코드를 push하면
- Jenkins/GitHub Actions 등이 코드를 자동으로 빌드하고 테스트 수행
- 테스트 통과 여부에 따라 병합 여부 결정
CD (지속적 제공/배포, Continuous Delivery / Deployment)
- Continuous Delivery (지속적 제공)
- CI 이후의 단계로, 테스트를 통과한 코드를 자동으로 staging 서버에 배포 가능한 상태로 만들어 둠.
하지만 실제 프로덕션 배포는 수동으로 진행. - 수동 승인만 하면 바로 운영 서버로 배포 가능
- 안정성과 배포 준비성 확보
- CI 이후의 단계로, 테스트를 통과한 코드를 자동으로 staging 서버에 배포 가능한 상태로 만들어 둠.
- Continuous Deployment (지속적 배포)
- 테스트까지 통과하면 자동으로 운영 서버에 배포까지 수행하는 방식
- 사람이 개입하지 않아도 코드 → 운영까지 자동화됨
- 빠른 피드백 루프 가능 (ex: A/B 테스트, 빠른 롤백 등)
CI/CD 도입 시 이점
- 배포 속도 향상
- 버그 조기 발견 및 수정
- 코드 품질 향상
- 반복 작업 감소 → 개발자는 핵심 로직에 집중 가능
관련 도구들
영역 | 도구 예시 |
버전 관리 | Git, GitHub, GitLab |
CI/CD 파이프라인 | Jenkins, GitHub Actions, GitLab CI/CD, CircleCI |
빌드 도구 | Maven, Gradle |
테스트 자동화 | JUnit, Mockito, Selenium |
배포 자동화 | Docker, Kubernetes, ArgoCD |
2. 왜 Docker인가
Docker는 현대 소프트웨어 개발에서 널리 사용되는 컨테이너 기반 가상화 기술이다.
개발, 테스트, 배포 환경을 표준화하고 자동화할 수 있다는 점에서 많은 개발자와 기업이 도입하고 있다.
Docker 사용 이유
- 개발과 배포가 편리하다
- Docker 컨테이너는 애플리케이션 실행에 필요한 모든 요소를 포함하므로, 환경 설정이 간단하다.
- 컨테이너 내부에서 다양한 소프트웨어를 설치하더라도 호스트 운영체제에 영향을 주지 않는다.
- 어떤 서버에서 실행하더라도 항상 동일한 환경을 보장하기 때문에 배포 오류를 줄일 수 있다.
- CI/CD 파이프라인에서 테스트 및 빌드 환경으로 자주 활용된다.
- 독립성과 확장성이 뛰어나다
- 애플리케이션을 서로 다른 컨테이너에 배포함으로써 각 애플리케이션이 서로 영향을 주지 않는다.
- 컨테이너 단위로 수평 확장이 가능하므로, 트래픽 증가에 유연하게 대응할 수 있다.
- 컨테이너는 가볍고 빠르게 실행되므로, 리소스 효율성도 높다.
- 컨테이너 기술의 사실상 표준이다
- Docker는 기존의 가상 머신에 비해 경량화되어 있으며, 실행 속도도 빠르다.
- 클라우드, DevOps, MSA 환경에서 사실상 표준으로 자리잡고 있다.
- 다양한 개발 도구 및 플랫폼과의 연동성이 뛰어나며, 생태계도 활발하다.
3. Docker 설치 - Window11
4. Docker 설치 후 Docker Test
Docker 엔진과 구성 확인
docker info
Container 실행 테스트
# nginx 이미지 다운받기
docker image pull nginx:1.25.3-alpine
docker images
docker image history nginx:1.25.3-alpine
docker run -d -p 8001:80 --name webserver01 nginx:1.25.3-alpine
docker ps | Select-String "webserver01"
docker port webserver01
curl http://localhost:8001
5. Docker Image
Docker Image
- Docker 이미지는 컨테이너 서비스를 위한 실행 환경을 정의한 읽기 전용 템플릿
- 애플리케이션 실행에 필요한 바이너리, 라이브러리, 설정 파일 등을 포함한다.
- 특징
- 상태 저장 없음 (Stateless)
- Docker 이미지는 애플리케이션 실행에 필요한 모든 파일과 라이브러리를 자체적으로 포함한다.
- 실행 환경에 영향을 받지 않고, 어디서든 동일한 애플리케이션을 실행할 수 있다.
- 이미지는 변경되는 상태값을 보유하지 않는다.
- 불변성 (Immutable)
- Docker 이미지는 한 번 생성되면 변경할 수 없다.
- 이미지를 수정하고 싶다면 기존 이미지를 기반으로 새로운 이미지를 생성해야 한다.
- 불변성은 배포 환경의 안정성과 일관성을 높이는 데 기여한다.
- 경량성
- 이미지는 필요한 파일만 포함하고 있기 때문에, 전통적인 가상 머신에 비해 용량이 작고 전송 속도도 빠르다.
- 버전 관리 및 캐싱이 용이하며, 레이어 구조로 인해 중복 없이 효율적으로 관리된다.
- 상태 저장 없음 (Stateless)
Docker Image 명령어
목적 | 명령어 | 설명 |
로컬 이미지 목록 확인 | docker image ls 또는 docker images | 로컬에 저장된 이미지 목록을 출력한다. |
이미지 다운로드 | docker image pull <이미지> | Docker Hub 또는 다른 레지스트리에서 이미지를 다운로드한다. |
이미지 업로드 | docker image push <이미지> | 로컬 이미지를 Docker Hub 등 원격 레지스트리에 업로드한다. |
이미지 빌드 | docker image build -t <이름>:<태그> <경로> | 지정된 Dockerfile을 기반으로 이미지를 빌드한다. |
이미지 삭제 | docker image rm <이미지> | 지정한 로컬 이미지를 삭제한다. (-f 옵션으로 강제 삭제 가능) |
태그 추가 | docker image tag <원본> <새이름>:<태그> | 기존 이미지에 새 이름(태그)을 부여한다. |
이미지 메타 정보 확인 | docker image inspect <이미지> | 이미지의 상세 정보를 JSON 형식으로 출력한다. |
이미지 히스토리 확인 | docker image history <이미지> | 이미지의 레이어별 생성 내역을 확인한다. |
사용하지 않는 이미지 정리 | docker image prune | 태그가 없는(dangling) 이미지들을 일괄 삭제한다. |
이미지 내보내기 | docker image save -o <파일>.tar <이미지> | 이미지를 tar 파일로 저장한다. (백업/전송용) |
이미지 불러오기 | docker image load -i <파일>.tar | 저장된 tar 파일로부터 이미지를 불러온다. |
자주 사용하는 명령어
# 1. 이미지 빌드
docker image build -t myapp:1.0 .
# 2. 빌드된 이미지 확인
docker image ls
# 3. 이미지의 레이어 히스토리 확인
docker image history myapp:1.0
# 4. 이미지 메타 정보 조회
docker image inspect myapp:1.0
# 5. 사용하지 않는 이미지 정리
docker image prune -f
6. Docker Container
Docker Container
- Docker Image를 실행한 인스턴스이며, 애플리케이션과 그 실행 환경을 격리된 상태로 실행하는 단위
이미지와 컨테이너의 관계
- 이미지(Image): 읽기 전용 템플릿 (설치본, 실행 파일 등)
- 컨테이너(Container): 이미지에서 실행된 프로세스 (실행 중인 프로그램)
컨테이너 동작 원리
- Dockerfile을 통해 이미지 생성
- 이미지를 기반으로 컨테이너 생성 및 실행
- 컨테이너는 이미지 위에 쓰기 가능한 레이어를 추가하여 동작
Docker Container 명령어
목적 | 명령어 | 설명 |
컨테이너 실행 | docker container run | 새로운 컨테이너를 생성하고 실행한다. (docker run 과 동일) |
실행 중인 컨테이너 목록 확인 | docker container ls | 현재 실행 중인 컨테이너 목록을 출력한다. |
모든 컨테이너 목록 확인 | docker container ls -a | 중지된 컨테이너를 포함한 전체 목록을 출력한다. |
컨테이너 내부 명령 실행 | docker container exec -it <컨테이너> <명령> | 실행 중인 컨테이너 내부에서 명령을 실행한다 (예: bash 진입). |
컨테이너 상태 상세 조회 | docker container inspect <컨테이너> | 컨테이너의 설정, 네트워크, 볼륨 등 상세 정보를 JSON 형식으로 출력한다. |
로그 확인 | docker container logs <컨테이너> | 해당 컨테이너의 stdout/stderr 로그를 출력한다. |
프로세스 확인 | docker container top <컨테이너> | 컨테이너 내부에서 실행 중인 프로세스 목록을 출력한다. |
리소스 사용량 확인 | docker container stats | 컨테이너의 CPU, 메모리, 네트워크 사용량 등을 실시간으로 확인한다. |
컨테이너 일시 중단 | docker container pause <컨테이너> | 컨테이너의 모든 프로세스를 일시 중단한다. |
일시 중단 해제 | docker container unpause <컨테이너> | pause 상태의 컨테이너를 다시 실행 상태로 전환한다. |
컨테이너 중지 | docker container stop <컨테이너> | 컨테이너를 정상 종료(SIGTERM → SIGKILL)한다. |
컨테이너 강제 종료 | docker container kill <컨테이너> | 즉시 SIGKILL 신호로 컨테이너를 종료한다. |
컨테이너 재시작 | docker container restart <컨테이너> | 컨테이너를 중지한 뒤 다시 시작한다. |
컨테이너 삭제 | docker container rm <컨테이너> | 중지된 컨테이너를 삭제한다. |
사용하지 않는 컨테이너 일괄 정리 | docker container prune | 중지된 모든 컨테이너를 한 번에 삭제한다. (확인 메시지 있음) |
자주 사용하는 명령어
# 1. nginx 컨테이너 실행
docker run --name web01 -d -p 8080:80 nginx
# 2. 실행 중인 컨테이너 목록 확인
docker container ls
# 3. 컨테이너 내부에 접속
docker exec -it web01 bash
# 4. 컨테이너 중지 및 삭제
docker stop web01
docker rm web01
'Backend > 강의' 카테고리의 다른 글
[🐋 Docker + CI/CD] 4. AWS 연동 (1) | 2025.07.03 |
---|---|
[🐋 Docker + CI/CD] 3-2. Docker 모니터링과 로깅 (0) | 2025.07.02 |
[🐋 Docker + CI/CD] 3-1. Dockerfile 과 Docker Compose (0) | 2025.07.02 |
[🐋 Docker + CI/CD] 2. Github actions를 활용한 CI/CD 파이프라인 (1) | 2025.07.01 |