5장. Docker 개념 — 왜 쓰는가
4장에서 우리는 투표 서비스를 내 컴퓨터에서 실제로 띄워 봤습니다. React 프론트, Express API, PostgreSQL이 모두 로컬에서 돌아가고, 브라우저로 투표하고 결과가 그래프로 보이는 것까지 확인했습니다. 정말 잘 만들었습니다.
그런데 여기서 한 가지 큰 벽을 만납니다. 이 서비스는 지금 "내 노트북에서만" 돕니다. 실제로 고객에게 서비스하려면, 내 노트북이 아니라 24시간 켜져 있는 서버에서 돌아야 합니다. 그 벽을 넘게 해 주는 도구가 이번 장의 주인공, Docker입니다.
이 장은 손으로 뭔가를 많이 만들기보다, 개념을 확실히 잡는 시간입니다. Docker는 이 책에서 처음 만나는 가장 큰 새 개념 중 하나입니다. 여기서 "이게 왜 필요하고 무엇인지"를 제대로 이해해 두면, 6장부터 이어지는 컨테이너 작업과 2부의 AWS 배포 전체가 훨씬 쉬워집니다. 대신 개념만 읽고 끝내지 않도록, 이 장 뒤쪽에서 Docker를 실제로 설치하고 컨테이너를 직접 하나 띄워 보며 손으로 만져 봅니다. 천천히 따라오세요.
[지금 여기]
우리는 22단계를 거쳐 "라이브 투표 서비스"를 직접 만들고, 컨테이너에 담아, AWS 클라우드에 배포합니다. 아래가 그 전체 여정 지도입니다. 지금은 5단계, Docker라는 새 개념을 배우는 자리에 있습니다.
- 1장개발 환경 준비 (터미널 / Node.js / Git / GitHub / VS Code / Claude Code)
- 2장Claude Code 사용법 익히기
- 3장무엇을 만들지 기획 (라이브 투표 서비스)
- 4장로컬에서 서비스 만들기 (React + Express + PostgreSQL)
- 5장Docker 개념
- 6장Dockerfile 작성
- 7장컨테이너 빌드·실행
- 8장AWS 시작 (계정 / IAM / 리전 / 비용)
- 9장이미지 태깅
- 10장ECR에 이미지 올리기
- 11장VPC 네트워크 구성
- 12장RDS 데이터베이스 생성
- 13장SSM 터널로 RDS 초기화
- 14장ECS Fargate + ALB로 배포 (기본 완성)
- 15장CI/CD (GitHub Actions)
- 16장IaC (Terraform)
- 17장배포 자동화 연결
- 18장현업 운영 구조 이해
- 19장무중단 배포
- 20장신규 버전 배포 & 롤백
- 21장(심화) 프론트를 Vercel로 분리 배포
- 22장마무리 (회고 + 리소스 삭제)
- 방금 끝낸 것: 4장에서 투표 서비스를 로컬에서 완성했습니다. 내 컴퓨터에서 React 프론트 + Express API + PostgreSQL이 함께 돌아가는 걸 확인했습니다.
- 이번 장에서 하는 것: 그 서비스를 "어디서든 똑같이 실행되는 상자"에 담기 위한 첫걸음으로, Docker가 무엇이고 왜 쓰는지 이해하고, 내 컴퓨터에 Docker를 설치해 컨테이너를 하나 직접 띄워 봅니다.
이번 장에서 완성되는 것
한 문장으로: Docker가 어떤 문제를 푸는 도구인지 설명할 수 있게 되고, 내 컴퓨터에 Docker Desktop을 설치해 컨테이너를 실제로 하나 띄웠다가 정리하는 것까지 손으로 해 봅니다.
이렇게 되면 성공입니다: VS Code 터미널에서 docker run hello-world가
Hello from Docker! 메시지를 보여 주고, nginx 컨테이너를 하나 띄운 뒤
브라우저 http://localhost:8080에서 "Welcome to nginx!" 화면을 직접
확인하고, 다시 그 컨테이너를 깔끔하게 지울 수 있게 됩니다.
사전 조건
이 장을 시작하기 전에 아래가 갖춰져 있어야 합니다.
- 1~4장 완료: 특히 4장까지 따라 해서, 투표 서비스가 내 컴퓨터에서
한 번이라도 정상적으로 돌아간 상태여야 합니다. (문서 폴더의
vote-app안에frontend,backend가 있고, 로컬에서 서비스를 띄워 봤다면 준비된 것입니다.) - 인터넷이 되는 노트북 (Windows 또는 macOS). 이 장에서 Docker Desktop을 내려받아 설치하고, 인터넷에서 테스트용 이미지를 몇 개 받습니다.
Docker 자체는 아직 안 깔려 있어도 됩니다. 이 장의 5.6절에서 설치합니다. 그러니 "Docker가 없는데?" 걱정하지 말고 그대로 따라오세요.
5.1 문제 상황 — "내 컴퓨터에선 되는데요"
개발 현장에서 가장 유명한 말이 있습니다. "제 컴퓨터에서는 되는데요."
무슨 상황일까요? 내 노트북에서는 서비스가 잘 돌아갑니다. 그런데 그 코드를 서버에 올리거나, 동료의 컴퓨터에서 실행하면 갑자기 안 됩니다. 바로 4장에서 만든 우리 투표 서비스를 예로 들어 봅시다. 이 서비스가 제대로 돌려면 아래 조건들이 필요합니다.
- Node.js가 특정 버전으로 깔려 있어야 한다
- PostgreSQL이 설치돼 있고, 특정 설정으로 실행 중이어야 한다
- 여러 부품(라이브러리)이 정확한 버전으로 갖춰져 있어야 한다
- 환경변수(
.env)가 올바르게 설정돼 있어야 한다
내 컴퓨터에는 이 모든 게 딱 맞게 갖춰져 있습니다(4장에서 그렇게 만들었으니까요). 하지만 서버나 동료 컴퓨터에는 Node.js 버전이 다르거나, PostgreSQL이 아예 없거나, 설정이 다를 수 있습니다. 조건 하나만 어긋나도 서비스는 실행되지 않습니다.
정리하면, 문제의 뿌리는 이것입니다.
프로그램은 "코드"만으로 돌지 않는다. 코드가 돌아가는 "환경"까지 똑같아야 제대로 돈다. 그런데 컴퓨터마다 환경이 다르다.
매번 새 컴퓨터에서 Node.js 깔고, PostgreSQL 깔고, 버전 맞추고, 설정 바꾸는 일을 손으로 반복하는 건 느리고, 실수가 잦고, 고통스럽습니다. 사람이 열 명이면 열 번, 서버가 다섯 대면 다섯 번 반복해야 합니다.
5.2 해결 아이디어 — 컨테이너
이 문제를 푸는 아이디어는 의외로 단순합니다. "코드만 옮기지 말고, 코드가 돌아가는 환경까지 통째로 상자에 담아서 옮기자."
이 상자를 컨테이너라고 부릅니다.
컨테이너(Container) 프로그램과, 그 프로그램이 돌아가는 데 필요한 모든 것(실행 환경, 라이브러리, 설정)을 하나로 묶어 담은 "상자"입니다. 이 상자는 어느 컴퓨터에 옮겨도 그 안에서는 항상 똑같은 환경이 유지됩니다. 그래서 "내 컴퓨터에선 되는데" 문제가 사라집니다.
비유 1: 택배 컨테이너
이 개념은 실제 항구의 화물 컨테이너에서 이름을 따왔습니다. 옛날에는 화물을 배에 실을 때, 물건 모양이 제각각이라 싣고 내리는 데 오래 걸리고 문제가 많았습니다. 그런데 규격이 똑같은 철제 컨테이너 상자에 물건을 담자, 배든 기차든 트럭이든 상자 단위로 똑같이 실어 나를 수 있게 됐습니다. 안에 뭐가 들었든 상자 규격은 같으니까요.
소프트웨어 컨테이너도 같은 발상입니다. 안에 든 프로그램이 무엇이든, 컨테이너라는 규격으로 담으면 어느 컴퓨터에서든 똑같이 실행할 수 있습니다.
비유 2: 즉석밥
집에서 밥을 지으려면 쌀, 물, 밥솥, 전기, 적당한 시간과 불 조절이 모두 필요합니다. 하나만 어긋나도 밥이 설익거나 탑니다. 반면 즉석밥은 데우기만 하면 어디서든(집이든 캠핑장이든 사무실이든) 똑같은 밥이 나옵니다. 이미 "밥이 되는 데 필요한 모든 것"이 그 용기 안에 담겨 굳어 있기 때문입니다. 컨테이너가 바로 이 즉석밥 같은 것입니다. 프로그램이 돌아가는 데 필요한 모든 것을 미리 담아 두어, 어디서 "데우든" 똑같이 실행됩니다.
Docker(도커) 이 컨테이너를 만들고 실행하는 가장 널리 쓰이는 도구입니다. "컨테이너 기술"이라는 개념을 실제로 쓸 수 있게 해 주는 프로그램이 Docker라고 보면 됩니다. 우리는 이 Docker로 투표 서비스를 상자에 담을 겁니다.
5.3 컨테이너 vs 가상머신 — 뭐가 다른가
"환경을 통째로 담는다"는 말을 들으면, 예전부터 있던 가상머신(VM)을 떠올리는 사람도 있습니다. 둘의 차이를 짚어 두면 컨테이너의 장점이 분명해집니다. 지금은 가볍게만 이해하면 됩니다.
가상머신(Virtual Machine, VM) 한 컴퓨터 안에 "가상의 컴퓨터"를 통째로 만들어 내는 기술입니다. 운영체제(윈도우, 리눅스 등)까지 통째로 흉내 냅니다.
핵심 차이는 이렇습니다.
- 가상머신: 컴퓨터를 통째로 하나 더 만듭니다. 운영체제까지 전부 포함하므로 무겁고(수 GB), 켜는 데 오래 걸리고(수십 초~분), 용량도 큽니다.
- 컨테이너: 운영체제는 내 컴퓨터 것을 공유하고, 프로그램과 그에 필요한 부분만 담습니다. 그래서 가볍고(수십~수백 MB), 순식간에 켜지고 (보통 1초 안팎), 용량도 작습니다.
한 문장으로: 컨테이너는 가상머신의 "환경을 똑같이 재현하는" 장점은 가져오면서, 무겁다는 단점은 덜어낸 방식입니다. 그래서 오늘날 서비스 배포에 컨테이너가 표준처럼 쓰입니다.
5.4 이미지와 레지스트리 — 컨테이너의 3형제
Docker를 쓰다 보면 세 가지 용어가 계속 나옵니다. 지금 확실히 구분해 두면 뒤에서 헷갈리지 않습니다.
이미지(Image) 컨테이너를 만들기 위한 "설계도 겸 붕어빵 틀"입니다. 프로그램과 환경이 어떻게 구성돼야 하는지를 담아 굳혀 놓은 파일입니다. 이미지 자체는 멈춰 있는 틀이고, 이걸로 실제 실행되는 컨테이너를 찍어냅니다.
컨테이너(Container) 이미지를 실제로 실행한 것입니다. 붕어빵 틀(이미지)로 찍어낸 붕어빵이 컨테이너입니다. 하나의 이미지로 여러 개의 컨테이너를 찍어낼 수 있습니다.
레지스트리(Registry) 이미지를 보관하고 공유하는 "창고"입니다. 내가 만든 이미지를 여기에 올려 두면, 다른 컴퓨터나 서버가 내려받아 실행할 수 있습니다. 스마트폰 앱스토어에 앱(이미지)을 올려 두면 누구나 내려받는 것과 비슷합니다.
세 형제의 관계를 흐름으로 보면 이렇습니다.
이게 우리가 앞으로 밟을 배포의 큰 그림입니다. 이미지를 만들고 → 레지스트리에 올리고 → 서버가 내려받아 컨테이너로 실행하는 흐름이죠. 지금은 이 세 단어의 뜻과 관계만 기억하면 됩니다. 뒤에 나올 실습에서 이 흐름을 직접 눈으로 보게 됩니다.
5.5 [활용 사례] 실무에서 Docker를 이렇게 쓴다
Docker가 우리 투표 서비스에만 쓰이는 특별한 도구라고 생각하면 오해입니다. Docker는 오늘날 거의 모든 개발 팀이 매일 쓰는 표준 도구입니다. 어디에 쓰이는지 대표적인 네 가지를 보면 "아, 이래서 실무에서 쓰는구나" 감이 옵니다.
사례 1. 새 팀원 온보딩 — 환경을 통째로 넘긴다
새 개발자가 팀에 들어오면, 예전에는 "우리 서비스를 돌리려면 Node는 이 버전, DB는 이거 깔고, 이 설정 바꾸고…" 하는 설치 안내서를 며칠에 걸쳐 따라 해야 했습니다. 그 과정에서 버전 하나만 어긋나도 하루를 날립니다. Docker를 쓰면 이 모든 환경을 상자로 묶어 두었기 때문에, 새 팀원은 명령 한 줄로 회사 서비스 전체를 자기 노트북에 그대로 띄웁니다. 설치 지옥이 사라집니다.
사례 2. 오픈소스나 데이터베이스를 명령 한 줄로 실행한다
PostgreSQL, Redis, MySQL 같은 프로그램을 예전 방식으로 깔려면 설치
파일 받고, 설정하고, 서비스 등록하는 번거로운 과정을 거쳤습니다.
Docker가 있으면 docker run 한 줄로, 내 컴퓨터를 더럽히지 않고 그
프로그램을 바로 띄웠다가, 필요 없어지면 상자째 깔끔히 지웁니다. 실제로
많은 개발자가 로컬 개발용 데이터베이스를 이렇게 컨테이너로 씁니다.
(우리도 4장에서 로컬 PostgreSQL을 이런 식으로 다뤘습니다.)
사례 3. CI 테스트 환경 — 매번 깨끗한 같은 환경에서 검사한다
코드를 GitHub에 올릴 때마다 자동으로 테스트를 돌리는 걸 CI라고 합니다 (3부에서 직접 만듭니다). 이때 매번 "완전히 똑같고 깨끗한 환경"에서 테스트해야 결과를 믿을 수 있습니다. Docker 컨테이너는 매번 새 상자를 찍어내 검사하고 버리므로, "지난번 테스트 찌꺼기 때문에 이번에 이상하게 동작"하는 일이 없습니다.
사례 4. 여러 버전을 동시에, 서로 안 부딪히게 돌린다
A 프로젝트는 PostgreSQL 15가 필요하고 B 프로젝트는 16이 필요하다면, 한 컴퓨터에 두 버전을 직접 깔면 서로 충돌하기 쉽습니다. 컨테이너로는 각각 다른 상자에 담아 동시에 띄울 수 있습니다. 상자끼리는 격리돼 있어 서로 간섭하지 않기 때문입니다. 같은 원리로, 큰 서비스를 여러 개의 작은 서비스(마이크로서비스)로 나눠 각각 컨테이너로 돌리는 방식이 현업에서 널리 쓰입니다.
정리하면, Docker는 "환경을 상자에 담아 어디서든 똑같이, 격리해서, 빠르게 실행"하게 해 줍니다. 이 성질 하나가 온보딩, 로컬 개발, 테스트, 배포까지 폭넓게 쓰이는 이유입니다.
5.6 [맛보기] Docker Desktop 설치하기
개념을 잡았으니, 이제 직접 만져 볼 차례입니다. 우리가 설치할 것은 Docker Desktop입니다.
Docker Desktop 개인 컴퓨터(macOS/Windows)에서 Docker를 쉽게 쓰도록 만든 프로그램입니다. 컨테이너를 실제로 돌리는 Docker 실행 엔진과, 상태를 눈으로 보는 관리 화면이 함께 들어 있습니다.
설치 방법 (공통 1단계)
- 웹브라우저에서 공식 사이트에 접속합니다:
https://www.docker.com - 화면의 Download Docker Desktop 버튼을 눌러, 내 운영체제에 맞는 설치 파일을 내려받습니다.
이제 운영체제별로 나뉩니다. 아래에서 내 것만 따라 하세요.
macOS인 경우
- 다운로드 버튼을 누르면 칩 종류를 고르게 됩니다. Apple 실리콘용과
인텔(Intel)용이 따로 있습니다.
- 내 칩이 뭔지 모르겠으면, 화면 왼쪽 위 사과 메뉴( ) → 이 Mac에 관하여를
열어 보세요. "칩(Chip)" 항목에
Apple M1/M2/M3…라고 적혀 있으면 Apple 실리콘,Intel이라고 적혀 있으면 인텔용을 받습니다.
- 내 칩이 뭔지 모르겠으면, 화면 왼쪽 위 사과 메뉴( ) → 이 Mac에 관하여를
열어 보세요. "칩(Chip)" 항목에
- 내려받은
Docker.dmg파일을 더블클릭해 엽니다. - 창이 열리면 고래 모양 Docker 아이콘을 오른쪽 Applications 폴더로 끌어다 놓습니다. (VS Code 설치 때와 똑같은 방식입니다.)
- Launchpad나 응용 프로그램(Applications) 폴더에서 Docker를 실행합니다. 처음 실행하면 약관 동의(Accept)나 권한 요청이 나오는데, 안내대로 기본값으로 넘어가면 됩니다. 중간에 비밀번호를 물으면 내 노트북 로그인 비밀번호를 입력합니다.
Windows인 경우
- 다운로드 버튼을 눌러
Docker Desktop Installer.exe를 내려받습니다. - 내려받은 설치 파일을 더블클릭해 실행합니다.
- 설치 화면이 나오면, 옵션은 기본값 그대로 두고 "OK / 다음"을 눌러 끝까지 진행합니다. (기본값에 WSL2 사용이 포함돼 있습니다. WSL2는 Windows에서 컨테이너가 리눅스처럼 돌게 해 주는 기능입니다.)
- 설치가 끝나면 "다시 시작(Restart)"을 요청할 수 있습니다. 안내대로 컴퓨터를 재시작합니다.
- 재시작 후 시작 메뉴에서 Docker Desktop을 실행합니다. 처음 실행 시 약관 동의나 간단한 설정을 물으면 기본값으로 넘어가면 됩니다.
Windows에서 WSL2 안내가 나오면 설치나 첫 실행 중 "WSL2를 설치/업데이트하라"는 안내가 나올 수 있습니다. 화면에 나온 링크나 버튼을 눌러 안내대로 진행하면 됩니다. 막히면 그 오류 메시지를 그대로 복사해 Claude Code에게 붙여넣고 도움을 받으세요.
설치 후: Docker Desktop이 켜져 있는지 확인
Docker Desktop은 켜져 있어야 명령이 먹힙니다 Docker로 뭔가를 실행하려면 Docker Desktop 프로그램이 실행 중이어야 합니다. 화면 위쪽 메뉴막대(macOS) 또는 오른쪽 아래 알림 영역(Windows)에 고래 모양 아이콘이 떠 있으면 켜진 상태입니다. 처음 켜면 고래 아이콘이 잠깐 움직이며 준비하는데, 움직임이 멈추고 안정적으로 표시될 때까지 (보통 몇십 초) 기다렸다가 다음 단계로 넘어가세요.
설치가 됐는지 터미널로 확인
이제 4장까지 계속 써 온 것처럼, VS Code에서 vote-app 폴더를 연 상태로
터미널(터미널 → 새 터미널)을 하나 엽니다. 앞으로 이 장의 모든 명령은
이 VS Code 통합 터미널에서 실행합니다. 아래를 입력하고 Enter를 누르세요.
docker --version # 설치된 Docker 버전을 보여 줍니다
Docker version 27.x.x ... 처럼 버전이 한 줄 나오면 설치 성공입니다.
(숫자는 사람마다 다를 수 있습니다. 나오기만 하면 됩니다.)
command not found: docker 가 나온다면, (1) Docker Desktop이
아직 실행되지 않았거나, (2) 방금 설치가 끝나 터미널이 새 명령을 아직
인식하지 못한 경우입니다. 먼저 Docker Desktop을 실행해 고래 아이콘이
뜬 걸 확인하고, 터미널 오른쪽 위 휴지통 아이콘으로 터미널을 닫은 뒤
터미널 → 새 터미널로 새로 열어 다시 입력해 보세요.
5.7 [맛보기] docker run hello-world — 흐름을 한 번 눈으로 보기
버전만 확인하는 것으로는 부족합니다. Docker가 실제로 "레지스트리에서
이미지를 내려받아 컨테이너로 실행"하는지, 아주 작은 테스트로 눈으로
확인해 봅시다. 같은 VS Code 터미널에 아래를 입력하고 Enter를 누르세요.
docker run hello-world # 테스트용 이미지를 받아 컨테이너로 실행
잠시 뒤 아래처럼 시작하는 메시지가 나오면 성공입니다.
Hello from Docker!
This message shows that your installation appears to be working correctly.
방금 5.4에서 그림으로 본 흐름이 실제로 한 번 일어났습니다.
방금 무슨 일이 일어났나
docker run hello-world 한 줄로, Docker는 (1) 내 컴퓨터에 그
hello-world 이미지가 없는 걸 확인하고, (2) 인터넷의 기본 레지스트리
(Docker Hub)에서 이미지를 내려받은 뒤, (3) 그 이미지로 컨테이너를 만들어
실행했습니다. 처음이라 "Unable to find image ... Pulling from ..." 같은
내려받는 메시지가 앞에 나올 수 있는데, 정상입니다.
5.8 [맛보기] nginx 컨테이너를 띄워 브라우저로 확인하고, 정리하기
hello-world는 메시지만 찍고 바로 끝나는 컨테이너였습니다. 이번에는
계속 켜져 있는 진짜 웹서버 컨테이너를 하나 띄워, 브라우저로 직접 접속해
보겠습니다. 여기까지 해 보면 "컨테이너가 실제로 돌아간다"는 게 손에
잡힙니다.
nginx(엔진엑스) 아주 널리 쓰이는 웹서버 프로그램입니다. 지금은 "브라우저로 접속하면 환영 페이지를 보여 주는, 이미 만들어진 프로그램" 정도로만 알면 됩니다. 우리가 설치할 필요 없이, Docker가 레지스트리에서 이미지를 받아 실행해 줍니다.
1단계. nginx 컨테이너 실행
같은 VS Code 터미널에 아래 한 줄을 입력하고 Enter를 누르세요.
docker run -d -p 8080:80 --name my-nginx nginx
각 부분의 뜻은 이렇습니다.
docker run: 이미지로 컨테이너를 만들어 실행하라-d: 백그라운드(detached)로 실행하라. 터미널을 계속 붙잡지 않고 뒤에서 돌게 합니다.-p 8080:80: 내 컴퓨터의8080포트를, 컨테이너 안 nginx가 쓰는80포트에 연결하라. (그래서 브라우저에서8080으로 접속하면 컨테이너 안 nginx로 전달됩니다.)--name my-nginx: 이 컨테이너에my-nginx라는 이름을 붙여라. 나중에 지울 때 이 이름으로 가리킵니다.nginx: 실행할 이미지 이름. 내 컴퓨터에 없으면 레지스트리에서 자동으로 받아 옵니다.
실행하면 처음엔 nginx 이미지를 내려받는 메시지가 지나가고, 마지막에 길고 복잡한 문자(컨테이너 ID)가 한 줄 출력되면서 커서가 다시 깜빡입니다. 이러면 컨테이너가 뒤에서 돌기 시작한 것입니다.
2단계. 컨테이너가 돌고 있는지 확인
지금 돌고 있는 컨테이너 목록을 봅시다.
docker ps # 지금 실행 중인 컨테이너 목록을 보여 줍니다
아래처럼 my-nginx 한 줄이 보이면 잘 돌고 있는 것입니다. (칸이 많아
줄바꿈되어 보일 수 있습니다.)
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
a1b2c3d4e5f6 nginx "/docker-entrypoint.…" ... 0.0.0.0:8080->80/tcp my-nginx
PORTS 칸에 8080->80이 보이면, 내 컴퓨터 8080이 컨테이너 80으로
연결됐다는 뜻입니다.
3단계. [확인] 브라우저로 직접 접속
웹브라우저(크롬, 사파리, 엣지 등)를 열고 주소창에 아래를 입력해 접속합니다.
http://localhost:8080
"Welcome to nginx!" 라는 환영 페이지가 뜨면 대성공입니다. 방금 여러분은 설치조차 한 적 없는 웹서버(nginx)를, Docker 명령 한 줄로 상자에 담긴 채로 띄우고, 브라우저로 실제 접속까지 해 본 것입니다.
localhost
"내 컴퓨터 자신"을 가리키는 주소입니다. localhost:8080은 "내 컴퓨터의
8080 포트"라는 뜻이고, 방금 -p 8080:80으로 그 포트를 컨테이너에
연결했기 때문에 nginx 화면이 보이는 것입니다.
4단계. 정리 — 컨테이너 멈추고 지우기
맛보기가 끝났으니, 띄운 컨테이너를 깔끔하게 치웁시다. 상자를 안 지우고 쌓아 두면 나중에 헷갈리므로, 실습이 끝나면 정리하는 습관이 좋습니다. VS Code 터미널에서 아래를 한 줄씩 실행합니다.
docker stop my-nginx # 돌고 있는 my-nginx 컨테이너를 멈춥니다
docker rm my-nginx # 멈춘 컨테이너를 완전히 지웁니다
각각 실행하면 my-nginx라는 이름이 한 줄씩 다시 출력됩니다. 그게 "그
컨테이너를 멈췄다 / 지웠다"는 확인입니다. 마지막으로 정말 정리됐는지
확인해 봅시다.
docker ps # 실행 중인 컨테이너 목록 (이제 비어 있어야 정상)
my-nginx 줄이 더 이상 보이지 않고 제목 줄만 나오면, 깔끔하게 정리된
것입니다. 브라우저에서 http://localhost:8080을 새로고침하면 이제
접속이 안 되는데(페이지를 표시할 수 없음), 컨테이너를 지웠으니 당연한
결과입니다.
docker stop은 컨테이너를 "잠시 멈추는" 것이고, docker rm은
멈춘 컨테이너를 "완전히 없애는" 것입니다. 그래서 rm 전에 반드시 stop을
먼저 합니다. (돌고 있는 걸 바로 지우려 하면 거부됩니다.)
5.9 지금까지 이해한 것 정리
이번 장에서 우리가 이해하고 손으로 확인한 것을 이어 붙이면 이렇게 됩니다.
- 4장에서 만든 투표 서비스는 "내 컴퓨터에서만" 돈다. 그 원인은 컴퓨터마다 환경이 다르기 때문이다.
- 그 문제를 푸는 방법이 컨테이너다. 프로그램과 환경을 상자에 통째로 담아 어디서든 똑같이 실행한다.
- 컨테이너는 이미지(붕어빵 틀)로 찍어내고, 이미지는 레지스트리(창고)에 올려 공유한다. 이게 배포의 큰 그림이다.
- 이 개념을 실제로 확인하려고, Docker Desktop을 설치하고
hello-world와 nginx 컨테이너를 직접 띄웠다가 정리해 봤다.
즉, Docker는 "내가 만든 서비스"와 "실제 서버 배포" 사이를 잇는 다리 입니다. 이 다리를 어떻게 건너는지는, 위 [지금 여기] 지도를 따라 한 걸음씩 익혀 갑니다.
[확인]
이번 장이 제대로 끝났는지 눈으로 확인합니다.
- VS Code 터미널에서
docker --version이 버전을 한 줄 보여 준다. docker run hello-world가Hello from Docker!메시지를 보여 줬다.docker run -d -p 8080:80 --name my-nginx nginx로 컨테이너를 띄운 뒤, 브라우저http://localhost:8080에서 "Welcome to nginx!"를 봤다.docker stop my-nginx→docker rm my-nginx로 정리했고,docker ps에 더 이상my-nginx가 보이지 않는다.
여기까지 보였다면, Docker가 무엇이고 왜 쓰는지 이해했고 손으로도 한 번 다뤄 본 것입니다.
막히면
이 장에서 초보자가 자주 막히는 지점과 대처법입니다.
-
command not found: docker가 나온다. Docker Desktop이 실행 중이 아니거나, 방금 설치 후 터미널이 새 명령을 아직 인식하지 못한 경우입니다. 먼저 Docker Desktop을 실행해 고래 아이콘이 뜬 걸 확인하고, 터미널을 휴지통 아이콘으로 닫은 뒤 터미널 → 새 터미널로 새로 열어 다시 입력하세요. -
Cannot connect to the Docker daemon ...같은 메시지가 나온다. Docker 명령은 되는데 엔진이 아직 안 켜진 상태입니다. Docker Desktop을 실행하고, 고래 아이콘의 움직임이 멈춰 "준비 완료"가 될 때까지(보통 몇십 초) 기다린 다음 명령을 다시 실행하세요. -
docker run hello-world가 한참 멈춰 있다. 처음엔 인터넷에서 이미지를 내려받느라 시간이 걸립니다. 회사·학교 네트워크나 방화벽 때문에 느릴 수도 있습니다. 잠시 기다려 보고, 계속 안 되면 다른 네트워크에서 시도해 보세요. -
브라우저에서
http://localhost:8080이 안 열린다. 먼저docker ps로my-nginx가 목록에 있는지 확인하세요. 목록에 없으면 컨테이너가 안 떠 있는 것이니 5.8절 1단계 명령을 다시 실행합니다. 목록에는 있는데 안 열린다면, 주소가 정확히http://localhost:8080인지 (포트 번호:8080까지) 다시 확인하세요. -
docker run에서port is already allocated같은 오류가 난다. 내 컴퓨터의 8080 포트를 다른 프로그램이 이미 쓰고 있는 경우입니다.docker run -d -p 8081:80 --name my-nginx nginx처럼 앞 숫자를8081로 바꿔 실행하고, 브라우저도http://localhost:8081로 접속하세요. -
docker rm이You cannot remove a running container ...라며 거부한다. 컨테이너가 아직 돌고 있어서입니다.docker stop my-nginx로 먼저 멈춘 뒤에docker rm my-nginx를 실행하세요. -
(Windows) 설치 중 WSL2 관련 오류가 난다. 화면에 나온 안내 링크로 WSL2를 설치/업데이트한 뒤 컴퓨터를 재시작하고 Docker Desktop을 다시 실행하세요. 오류 메시지를 그대로 복사해 Claude Code에게 붙여넣으면 상황에 맞는 해결을 안내받을 수 있습니다.
[체크리스트]
아래가 모두 됐는지 확인해 보세요. 하나라도 안 됐다면 해당 절로 돌아가 다시 진행합니다.
- □ "내 컴퓨터에선 되는데" 문제의 원인(환경 차이)을 설명할 수 있다
- □ 컨테이너가 무엇이고, 왜 그 문제를 해결하는지 안다
- □ 컨테이너와 가상머신의 차이를 한 문장으로 말할 수 있다
- □ 이미지 / 컨테이너 / 레지스트리 세 용어의 관계를 설명할 수 있다
- □ Docker가 실무에서 어디에 쓰이는지 사례를 두어 개 댈 수 있다
- □ Docker Desktop을 설치했고, 고래 아이콘이 켜져 있다
- □
docker --version과docker run hello-world가 정상 동작한다 - □ nginx 컨테이너를 띄워
http://localhost:8080에서 환영 페이지를 봤다 - □
docker stop/docker rm으로 컨테이너를 정리했고docker ps가 비었다
모두 체크됐다면, Docker의 개념을 이해하고 손으로도 다뤄 본 것입니다.