개념
"내 컴퓨터에서는 되는데요"
모듈 7(레슨 3)에서 배운 환경 패리티 문제를 떠올려보자 — 개발자 로컬 환경, CI 서버 환경, 운영 환경이 OS 버전, 설치된 라이브러리 버전, 설정값이 미묘하게 다르면, 같은 코드도 다르게 동작한다. 이건 CI/CD에서 특히 골치 아픈 문제다 — 사람이 매번 환경 차이를 맞춰볼 수 없기 때문이다.
컨테이너(Container)란
Docker는 애플리케이션과 그것이 필요로 하는 모든 것(라이브러리 버전, 설정, 실행 환경)을 하나의 컨테이너 이미지로 통째로 포장하는 기술이다.
가상 머신(VM): OS 전체를 통째로 복제 — 무겁고 느림
컨테이너(Docker): 필요한 라이브러리·설정만 포장 — 가볍고 빠름컨테이너는 "이 이미지 안에는 정확히 이 버전의 Node.js, 이 라이브러리들, 이 설정이 들어있다"를 보장한다 — 개발자 로컬에서 실행하든, CI 서버에서 실행하든, 정확히 같은 환경에서 코드가 돈다.
Dockerfile — 환경을 코드로 정의하기
FROM node:20
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
CMD ["npm", "run", "test"]이 파일은 "Node.js 20 버전을 기반으로, 의존성을 설치하고, 코드를 복사한 뒤, 테스트를 실행하라"는 환경 구성을 코드로 명시한다. 모듈 8(레슨 6)에서 배운 "산출물 문서로 프로세스를 명시한다"는 원칙이, 여기서는 "환경 자체를 코드로 문서화한다"는 형태로 나타난다.
CI에서 Docker를 쓰는 이유
Docker 없이: CI 서버에 필요한 도구·버전을 매번 수동으로 설치·관리
Docker 사용: 이미 만들어둔 이미지를 그대로 가져와 실행 — 항상 같은 환경 보장레슨 2에서 배운 GitHub Actions 워크플로 안에서도 Docker 컨테이너를 지정해 그 안에서 테스트를 실행하도록 구성할 수 있다. 이러면 "CI 서버의 OS가 업데이트돼서 갑자기 테스트가 깨졌다" 같은 문제를 원천적으로 방지한다.
QA 입장에서 Docker가 주는 가치
- 버그 재현이 정확해진다 — "이 버그가 있던 정확한 환경"을 컨테이너 이미지로 고정해두면, 나중에 다시 그 환경에서 재현해 확인할 수 있다
- 테스트 환경 구축(모듈 7 레슨 3)이 빨라진다 — 매번 서버를 새로 세팅하지 않고, 이미지를 실행하기만 하면 된다
- "환경 문제인지 코드 문제인지" 구분이 쉬워진다 — 같은 컨테이너 이미지에서 재현이 안 된다면, 환경 문제가 아니라 진짜 코드나 데이터 문제일 가능성이 높아진다
실무에서 왜 필요한가
"로컬에서는 통과, CI에서는 실패"라는 증상이 나오면, Docker화된 CI 환경을 쓰는 팀은 "적어도 CI 자체의 환경 차이 때문은 아니다"라는 확신을 갖고 다른 원인(레슨 5의 False Alarm 관점)을 찾아볼 수 있다. QA가 Docker의 기본 개념을 이해하면, "이 결함을 재현하려면 어떤 환경이 필요한지"를 결함 리포트(모듈 6 레슨 2)에 훨씬 정확하게 기록할 수 있다.