바이브코딩 서비스를 Docker 컨테이너로 실전서비스 론칭하기 · 1부 — 바이브코딩 셋업부터 컨테이너 실행까지

7장. 컨테이너 빌드 · 실행

1부의 마지막 장입니다. 6장에서 이미지를 만드는 설명서(Dockerfile)를 준비했습니다. 이제 그 설명서로 실제 이미지를 굽고(빌드), 컨테이너로 실행하고, 마지막에는 프론트엔드 · API · 데이터베이스 세 상자를 명령 한 번으로 한꺼번에 띄워, 우리 투표 서비스가 "상자 안에서" 도는 것을 브라우저로 확인합니다. 5장의 붕어빵 비유로 하면, 설계도(Dockerfile)로 틀(이미지)을 만들고, 그 틀로 붕어빵(컨테이너)을 굽는 단계입니다.

명령어가 몇 개 나오지만, 대부분 Claude Code에게 시키면 됩니다. 다만 각 명령이 무슨 뜻인지 알아 두면 문제가 생겼을 때 스스로 대응할 수 있으니, 뜻풀이를 함께 봅니다.

[지금 여기]

우리는 22단계를 거쳐 "라이브 투표 서비스"를 만들고, 컨테이너에 담아, AWS 클라우드에 배포합니다. 아래가 그 전체 여정 지도입니다. 지금은 7단계, 1부의 마지막에 있습니다.

  1. 1장개발 환경 준비 (터미널 / Node.js / Git / GitHub / VS Code / Claude Code)
  2. 2장Claude Code 사용법 익히기
  3. 3장무엇을 만들지 기획 (라이브 투표 서비스)
  4. 4장로컬에서 서비스 만들기 (React + Express + PostgreSQL)
  5. 5장Docker 개념
  6. 6장Dockerfile 작성
  7. 7장컨테이너 빌드·실행
  8. 8장AWS 시작 (계정 / IAM / 리전 / 비용)
  9. 9장이미지 태깅
  10. 10장ECR에 이미지 올리기
  11. 11장VPC 네트워크 구성
  12. 12장RDS 데이터베이스 생성
  13. 13장SSM 터널로 RDS 초기화
  14. 14장ECS Fargate + ALB로 배포 (기본 완성)
  15. 15장CI/CD (GitHub Actions)
  16. 16장IaC (Terraform)
  17. 17장배포 자동화 연결
  18. 18장현업 운영 구조 이해
  19. 19장무중단 배포
  20. 20장신규 버전 배포 & 롤백
  21. 21장(심화) 프론트를 Vercel로 분리 배포
  22. 22장마무리 (회고 + 리소스 삭제)

이번 장에서 완성되는 것

한 문장으로: 6장의 Dockerfile로 이미지를 빌드하고, docker compose로 프론트엔드 · API · DB 세 컨테이너를 한꺼번에 띄워, 투표 서비스가 전부 컨테이너 안에서 도는 것을 브라우저로 확인합니다.

이렇게 되면 성공입니다: VS Code 터미널에서 docker compose up을 실행한 뒤 브라우저로 http://localhost:8080에 접속하면, 4장에서 만든 것과 똑같은 투표 화면이 뜨고, 설문 만들기 · 투표 · 결과 그래프 · 새로고침 후 유지까지 전부 동작합니다. 다만 이번엔 로컬에 직접 깐 게 아니라 전부 컨테이너 안에서 돌고 있습니다.

사전 조건

이 장은 1~6장의 결과물 위에서 시작합니다. 아래가 갖춰져 있어야 합니다.

시작 전에 Docker가 켜져 있는지 확인

VS Code에서 Terminal(터미널) → New Terminal(새 터미널)로 터미널을 열고 (새 터미널은 항상 vote-app 폴더에서 시작합니다), 아래를 한 줄씩 입력합니다.

docker --version    # 설치된 Docker 버전을 보여 준다
docker ps           # 지금 실행 중인 컨테이너 목록을 보여 준다

docker --version이 버전을 보여 주고, docker ps가 오류 없이 표의 제목 줄(CONTAINER ID IMAGE ...)을 보여 주면 준비 완료입니다.

주의

docker ps에서 Cannot connect to the Docker daemon이라는 메시지가 나오면 Docker Desktop이 실행 중이 아닙니다. Docker Desktop을 켜고 고래 아이콘이 안정될 때까지 기다린 뒤 다시 입력하세요.

7.1 이미지 빌드 — docker build

(1) 개념 — 빌드가 무엇인가

6장에서 만든 Dockerfile은 아직 "설명서"일 뿐입니다. 이 설명서를 실제 이미지로 바꾸는 과정을 빌드(build)라고 하고, 그 명령이 docker build 입니다.

용어

docker build Dockerfile(설명서)을 읽어, 그 순서대로 실행하면서 이미지를 만들어 내는 명령입니다. 레시피(Dockerfile)를 보고 실제로 요리(이미지)를 완성하는 단계라고 보면 됩니다.

빌드한 이미지에는 이름표(태그)를 붙입니다. 이름을 붙여 둬야 나중에 그 이름으로 실행하거나 클라우드에 올릴 수 있습니다.

용어

-t(태그, tag) 만들 이미지에 붙이는 이름입니다. docker build -t vote-api . 는 "이 이미지를 vote-api라는 이름으로 만들어라"라는 뜻입니다. 2부에서 이 태그가 버전 관리 · 롤백과 어떻게 연결되는지 더 다룹니다.

명령의 생김새는 이렇습니다.

docker build -t vote-api .

(2) 활용 사례 — 빌드는 어디에 쓰이나

(3) [맛보기] 아주 작은 이미지 하나 직접 빌드해 보기

우리 프로젝트를 빌드하기 전에, 연습으로 아주 작은 이미지 하나를 직접 만들어 봅니다. 우리 프로젝트를 건드리지 않도록 문서 폴더에 연습용 폴더를 따로 만들어서 합니다.

  1. VS Code에서 파일 → 폴더 열기(Open Folder)를 누릅니다. 문서(Documents) 폴더로 간 뒤, 창의 새 폴더(New Folder) 버튼으로 docker-hello 폴더를 만들고 그 폴더를 엽니다. (우리 프로젝트를 건드리지 않도록 vote-app 바깥에 따로 만드는 것입니다.) 이제 VS Code 왼쪽 탐색기에 빈 docker-hello 폴더가 열립니다.

  2. 이 폴더에 아주 짧은 Dockerfile을 하나 만듭니다. 왼쪽 탐색기에서 docker-hello 위에 마우스를 올리면 나타나는 새 파일(New File) 아이콘을 눌러, 파일 이름을 Dockerfile(확장자 없이 그대로)로 짓습니다. 그리고 열린 빈 파일에 아래 내용을 복사해 붙여넣고 저장합니다(Ctrl/Cmd + S).

FROM alpine
CMD ["echo", "Hello from Docker!"]
  1. 이 폴더에서 이미지를 빌드합니다. VS Code에서 터미널 → 새 터미널(New Terminal)을 열면 방금 연 docker-hello 폴더에서 시작합니다. 아래를 입력하세요.
docker build -t hello-docker .   # 지금 폴더의 Dockerfile로 hello-docker 이미지를 만든다

FROM alpine 이미지를 내려받고 층(레이어)을 쌓는 모습이 터미널에 주르륵 나오고, 마지막에 성공 메시지가 나오면 이미지가 만들어진 것입니다.

  1. 만들어진 이미지를 목록으로 확인합니다.
docker images        # 내 컴퓨터에 있는 이미지 목록을 보여 준다

목록의 REPOSITORY 칸에 hello-docker가 보이면 성공입니다. (내친김에 docker run hello-docker를 실행하면 Hello from Docker!가 출력됩니다. 실행 명령은 바로 다음 7.2에서 자세히 다룹니다.)

방금 여러분은 설명서 한 장으로 진짜 이미지를 처음 구워 봤습니다. 이게 docker build의 전부입니다.

(4) [우리 프로젝트] 우리 서비스 이미지 빌드하기

이제 6장에서 준비한 Dockerfile로 우리 서비스의 이미지 두 개(vote-api, vote-web)를 빌드합니다.

먼저 다시 vote-app으로 돌아가야 합니다. 헷갈리지 않게, 새 터미널을 여세요. VS Code에서 Terminal → New Terminal로 새 터미널을 열면 항상 vote-app 폴더에서 시작합니다. (앞의 맛보기에서 docker-hello로 옮겨 간 터미널 대신 깨끗한 새 터미널로 이어 갑니다.)

  1. 백엔드(API 서버) 이미지를 빌드합니다. Dockerfile은 backend 폴더 안에 있으니, 그 폴더로 들어가서 빌드합니다.
cd backend                  # vote-app 안의 backend 폴더로 이동
docker build -t vote-api .  # backend/Dockerfile로 vote-api 이미지를 만든다
  1. 프론트엔드 이미지를 빌드합니다.
cd ../frontend              # backend에서 나와 frontend 폴더로 이동
docker build -t vote-web .  # frontend/Dockerfile로 vote-web 이미지를 만든다

프론트엔드는 6장에서 본 멀티스테이지 방식이라, "빌드 단계"와 "Nginx로 담는 단계"가 차례로 지나가는 게 보입니다.

  1. 두 이미지가 잘 만들어졌는지 확인합니다.
docker images       # 이미지 목록 확인

목록에 vote-apivote-web이 둘 다 보이면 성공입니다.

프롬프트

Claude Code에게 시키려면 위 과정을 직접 치는 대신 Claude Code에게 맡겨도 됩니다. vote-app에서 claude를 실행한 뒤 이렇게 요청하세요.

backend와 frontend 이미지를 각각 vote-api, vote-web 이라는 이름으로
빌드해 줘. 빌드가 성공했는지 docker images로 확인해서 알려 줘.

7.2 컨테이너 실행 — docker run

(1) 개념 — 실행이 무엇인가

이미지(틀)가 준비됐으니, 이제 그 틀로 컨테이너(붕어빵)를 찍어 냅니다. 이걸 하는 명령이 docker run입니다.

용어

docker run 이미지를 실제로 실행해 컨테이너로 띄우는 명령입니다. docker build가 "틀을 만드는" 것이라면, docker run은 "그 틀로 붕어빵을 굽는" 것입니다.

API 서버를 실행하는 명령의 생김새는 이렇습니다.

docker run -p 3000:3000 --env-file .env vote-api

여기서 가장 헷갈리는 게 포트 매핑입니다. 짚고 갑시다.

용어

포트(Port) 한 컴퓨터 안에서 프로그램들이 통신하려고 쓰는 "번호가 붙은 창구"입니다. 예를 들어 우리 API 서버는 3000번 창구로 요청을 받습니다.

용어

포트 매핑(Port Mapping) — -p 컨테이너는 5장에서 배웠듯 "상자"라, 그 안의 창구(포트)는 바깥에서 바로 보이지 않습니다. 그래서 "내 컴퓨터의 몇 번 창구를 → 상자 안의 몇 번 창구로 연결한다"고 지정해 줘야 합니다. 이게 포트 매핑입니다. -p 3000:3000은 "내 컴퓨터 3000번 → 컨테이너 3000번으로 연결"이라는 뜻입니다. 앞이 내 컴퓨터, 뒤가 상자 안쪽입니다.

용어

환경변수 주입 — --env-file 4장에서 비밀번호 같은 민감한 값을 .env 파일로 분리했습니다. 컨테이너는 상자라서 그 값을 안에서 알 수 없으므로, 실행할 때 --env-file .env로 넣어 줍니다. 이렇게 하면 비밀번호를 이미지에 구워 넣지 않고도 전달할 수 있습니다.

(2) 활용 사례 — docker run은 어디에 쓰이나

(3) [맛보기] 컨테이너를 띄워 브라우저로 보기

포트 매핑을 손으로 느껴 보는 게 좋습니다. 공개된 nginx(웹 서버) 이미지를 띄워, 내 컴퓨터 포트로 접속해 봅니다.

  1. 아무 터미널에서나(위치는 상관없습니다) 아래를 입력합니다.
docker run -d -p 8080:80 nginx    # nginx를 백그라운드로 띄우고, 내 컴퓨터 8080 → 컨테이너 80 연결
  1. 브라우저를 열어 주소창에 http://localhost:8080을 입력합니다. "Welcome to nginx!" 페이지가 보이면 성공입니다. 방금 브라우저의 요청이 포트 매핑(8080 → 80)을 타고 상자 안 Nginx까지 전달된 것입니다.

  2. 확인이 끝났으면 이 연습용 컨테이너를 멈춥니다.

docker ps           # 실행 중인 컨테이너 목록. 맨 앞 CONTAINER ID(예: a1b2c3d4)를 확인
docker stop a1b2c3d4   # 그 CONTAINER ID로 컨테이너를 멈춘다 (자기 값으로 바꿔 입력)

(4) [우리 프로젝트] API 컨테이너 실행 명령 이해하기

우리 API도 방금 배운 방식으로 실행합니다. backend 폴더에서(그래야 옆에 있는 .env--env-file .env로 바로 가리킬 수 있습니다) 이렇게 실행합니다.

docker run -p 3000:3000 --env-file .env vote-api

그런데 여기서 중요한 사실이 하나 있습니다. 이렇게 API 하나만 띄우면, API는 켜지지만 옆에 붙을 데이터베이스가 없어서 완전히 동작하지는 않습니다. 우리 서비스는 부품이 세 개(프론트엔드 · API · DB)이고, 이 셋이 서로 연결돼야 제대로 돕니다. 그래서 컨테이너를 하나씩 docker run으로 따로 띄우고 서로 연결까지 신경 쓰는 건 번거롭습니다.

이 명령을 실제로 실행해 API 컨테이너가 뜨는 모습만 잠깐 봐도 좋습니다. 확인했으면 터미널에서 Ctrl + C를 눌러 멈추세요. 세 컨테이너를 함께 띄우는 깔끔한 방법은 바로 다음 7.3의 docker compose입니다.

7.3 세 컨테이너를 한 번에 — docker compose

(1) 개념 — docker compose가 무엇인가

7.2 끝에서 본 문제, "부품이 셋이라 하나씩 띄우고 연결하기가 번거롭다"를 푸는 도구가 docker compose입니다.

용어

docker compose(도커 컴포즈) 여러 컨테이너를 하나의 설정 파일에 정의해 두고, 명령 한 번으로 한꺼번에 실행 · 중지하는 도구입니다. "우리 서비스는 이 세 상자로 이루어진다"를 한 파일에 적어 두는 셈입니다.

용어

docker-compose.yml compose가 읽는 설정 파일입니다. 어떤 컨테이너들을(services), 어떤 이미지 또는 어떤 Dockerfile로, 어떤 포트와 환경변수로 띄울지를 적습니다. .yml은 사람이 읽기 쉬운 형식의 설정 파일 확장자입니다.

용어

docker compose up / down - up: 설정 파일에 정의된 컨테이너들을 한꺼번에 띄운다. - down: 그 컨테이너들을 한꺼번에 멈추고 정리한다.

(2) 활용 사례 — compose는 어디에 쓰이나

(3) [맛보기] compose로 컨테이너 하나 띄우고 내리기

먼저 아주 작은 compose를 손으로 만져 봅니다. 앞서 만든 연습용 폴더 docker-hello를 다시 씁니다. (VS Code에서 그 폴더가 열려 있지 않다면, 파일 → 폴더 열기로 문서 폴더의 docker-hello를 다시 엽니다.)

  1. 이 폴더에 docker-compose.yml 파일을 하나 만듭니다. 왼쪽 탐색기에서 docker-hello 위의 새 파일(New File) 아이콘을 눌러 이름을 docker-compose.yml로 짓고, 열린 파일에 아래 내용을 복사해 붙여넣고 저장합니다.
services:
  web:
    image: nginx
    ports:
      - "8081:80"
주의

들여쓰기(띄어쓰기)가 중요합니다 .yml 파일은 줄 앞의 띄어쓰기 칸 수로 상하 관계를 나타냅니다. 위 내용을 그대로 복사해 붙여넣으면 칸이 맞습니다. 직접 칠 때는 탭이 아니라 스페이스로, 예시와 같은 칸 수로 맞춰야 합니다.

  1. compose로 띄웁니다. VS Code에서 터미널 → 새 터미널을 열면 docker-hello 폴더에서 시작합니다. 아래를 입력하세요.
docker compose up -d     # 설정에 정의된 컨테이너를 백그라운드로 띄운다

브라우저에서 http://localhost:8081에 접속해 "Welcome to nginx!"가 보이면 성공입니다.

  1. 다 봤으면 내립니다.
docker compose down      # 이 compose로 띄운 컨테이너를 한꺼번에 멈추고 정리

up으로 띄우고 down으로 내린다 — compose의 기본 리듬을 손으로 익혔습니다.

(4) [우리 프로젝트] 프론트 컨테이너가 API를 찾게 하기 — Nginx 프록시

세 컨테이너를 묶기 전에, 프론트 이미지에 손질이 하나 필요합니다. 6장에서 만든 프론트 이미지의 Nginx는 지금 화면 파일만 서빙합니다. 그런데 컨테이너로 띄우면, 브라우저가 보내는 /api 요청을 API 서버로 넘겨줄 사람이 없습니다. 4장에서 그 일을 하던 Vite 개발 프록시는 개발용이라, 빌드된 이미지 안에는 없기 때문입니다.

그래서 이번엔 web의 Nginx가 /api 요청을 api 컨테이너로 넘기도록 설정을 추가합니다. 프론트 코드는 그대로 상대 경로(/api)로 부르고, 넘겨주는 역할만 개발 프록시에서 Nginx로 바뀌는 것입니다.

프롬프트
frontend의 Nginx가 /api로 시작하는 요청을 api 컨테이너(3000)로
프록시하도록 설정을 추가해 줘. 프록시 대상 주소는 환경변수(API_URL)로
받아서, docker compose에서는 api 서비스를, 나중에 AWS ECS(같은 태스크)
에서는 localhost를 가리킬 수 있게 해 줘. 프론트는 계속 상대 경로(/api)로
부르면 돼.
용어

리버스 프록시(Reverse Proxy) 요청을 대신 받아 뒤의 서버로 넘겨주는 중계입니다. 여기서는 Nginx가 브라우저의 /api 요청을 받아 api 컨테이너로 넘깁니다. 브라우저 입장에서는 늘 같은 주소(web)와만 대화하므로 CORS가 생기지 않습니다. 이 아이디어는 2부에서 로드밸런서(ALB)로 규모를 키워 다시 만납니다. [참고] 왜 대상 주소를 환경변수로 받나 — 로컬과 AWS의 차이 docker compose에서는 컨테이너마다 네트워크가 나뉘어 있어 상대 컨테이너를 서비스 이름(api)으로 불러야 합니다. 반면 AWS ECS에서는 web과 api를 한 태스크에 담아 localhost로 통신합니다. 실행 환경에 따라 달라지는 값이므로 — 1부에서 배운 원칙대로 — 환경변수(API_URL)로 분리합니다. 그래서 compose에서는 API_URL=http://api:3000을 넣어 줍니다.

(5) [우리 프로젝트] 프론트엔드 · API · DB를 한 파일로

이제 우리 서비스의 세 컨테이너(web · api · db)를 한 파일에 담습니다. 파일은 vote-app 폴더의 맨 위(루트)docker-compose.yml이라는 이름으로 둡니다. Claude Code에게 만들어 달라고 합시다. (vote-app에서 claude 실행 후.)

프롬프트
vote-app 루트에 docker-compose.yml을 만들어 줘. 서비스 3개:
- db: postgres:16 이미지. 4장 .env의 DB 이름/사용자/비밀번호를 쓰고,
  준비됐는지 검사하는 healthcheck를 넣어 줘.
- api: backend 폴더의 Dockerfile로 빌드. 포트 3000:3000. .env를 env_file로
  넣되, DB 접속 host는 db 컨테이너를 가리키게 해 줘. db가 healthy해진 뒤에
  뜨도록 depends_on 조건을 걸어 줘.
- web: frontend 폴더의 Dockerfile로 빌드. 포트 8080:80. api 다음에 뜨게.
  web의 Nginx가 /api를 넘길 대상(API_URL)은 http://api:3000 으로 넣어 줘.
각 항목에 주석으로 설명을 달아 줘.

만들어진 파일은 대략 이런 구조입니다(세부는 조금 다를 수 있습니다).

services:
  db:                              # 데이터베이스 컨테이너
    image: postgres:16            # 공개된 postgres 이미지를 그대로 사용
    environment:                   # DB 초기 설정 (실제로는 .env 값으로 채웁니다)
      POSTGRES_DB: voteapp
      POSTGRES_USER: voteuser
      POSTGRES_PASSWORD: 비밀번호
    healthcheck:                   # DB가 접속을 받을 준비가 됐는지 검사
      test: ["CMD-SHELL", "pg_isready -U voteuser -d voteapp"]
      interval: 5s
      timeout: 3s
      retries: 5

  api:                             # API 서버 컨테이너
    build: ./backend               # backend 폴더의 Dockerfile로 빌드
    ports:
      - "3000:3000"                # 내 컴퓨터 3000 → 컨테이너 3000
    env_file: .env                 # .env의 환경변수를 넣어 준다
    environment:
      DB_HOST: db                  # DB 접속 host는 db 컨테이너(서비스 이름)
    depends_on:
      db:
        condition: service_healthy # db가 healthy해진 뒤에 api를 띄운다

  web:                             # 프론트엔드 컨테이너 (Nginx)
    build: ./frontend              # frontend 폴더의 Dockerfile로 빌드
    ports:
      - "8080:80"                  # 내 컴퓨터 8080 → 컨테이너 80(Nginx)
    environment:
      API_URL: http://api:3000     # Nginx가 /api 요청을 넘길 대상(compose에선 api 서비스)
    depends_on:
      - api                        # api 다음에 web을 띄운다

주목할 점 몇 가지만 짚습니다.

용어

컨테이너끼리는 "서비스 이름"으로 서로를 찾는다 compose로 함께 띄운 컨테이너들은 서로 이름으로 통신합니다. 그래서 API가 DB에 접속할 때 주소(host)는 localhost가 아니라 db(DB 서비스의 이름)입니다. 4장에서 로컬로 돌릴 때는 host가 localhost였지만, compose 안에서는 상대 컨테이너의 서비스 이름을 host로 씁니다. 그래서 위에서 DB_HOST: db로 지정했습니다. [참고] DB 안의 테이블(스키마)은 준비돼 있어야 합니다 compose의 db새로 뜨는 빈 데이터베이스입니다. 4장에서 만든 테이블이 이 안에는 아직 없을 수 있습니다. 투표 화면은 뜨는데 저장이 안 되거나 "테이블이 없다"는 오류가 보이면, Claude Code에게 이렇게 부탁하세요.

db 컨테이너가 처음 뜰 때 4장에서 만든 테이블 생성 SQL이 자동으로
실행되도록 docker-compose.yml에 연결해 줘. (postgres 초기화 스크립트 방식)

한 번에 실행하기

vote-app 루트에서(새 터미널을 열면 여기서 시작합니다) 아래를 실행합니다.

docker compose up --build

멈출 때는 이 터미널에서 Ctrl + C를 누르거나, 다른 터미널을 열어 vote-app에서 아래를 입력합니다.

docker compose down       # 세 컨테이너를 한꺼번에 멈추고 정리

7.4 전체 서비스 동작 확인

이제 진짜 확인입니다. 4장에서는 컨테이너 없이 로컬에서 직접 실행했지만, 이번에는 전부 컨테이너(상자) 안에서 돌고 있습니다.

docker compose up --build가 정상적으로 떴다면(터미널 로그가 오류 없이 흐르고 API가 요청을 기다린다는 메시지가 보이면), 브라우저를 열어 프론트엔드 주소 http://localhost:8080으로 접속합니다. 그리고 3장의 완료 기준을 하나씩 확인합니다.

모두 통과했다면, 정말 중요한 이정표를 지난 것입니다. 우리 서비스가 이제 어느 컴퓨터에서든 똑같이 실행될 수 있는 상자에 담겼습니다. 2부에서 이 상자(이미지)를 AWS로 옮기면, 그대로 인터넷에 서비스할 수 있습니다.

참고

왜 이게 대단한가 5장에서 이야기한 "내 컴퓨터에선 되는데" 문제를, 방금 여러분이 해결했습니다. 이 컨테이너들은 동료의 컴퓨터에서도, AWS 서버에서도 똑같이 돕니다. Node.js 버전이나 PostgreSQL 설치 여부를 신경 쓸 필요가 없습니다. 전부 상자 안에 들어 있으니까요.

확인이 끝났으면 컨테이너를 정리해 둡니다. up을 실행한 터미널에서 Ctrl + C를 누르거나, 다른 터미널(vote-app)에서 docker compose down을 실행합니다. (연습용으로 만든 docker-hello 폴더도 이제 필요 없으니 지워도 됩니다.)

7.5 1부 정리 & 자주 나는 오류

1부에서 한 일 되짚기

1부에서 우리는 아무것도 없는 노트북에서 시작해 여기까지 왔습니다.

자주 나는 오류와 대처

실습 중 아래와 비슷한 문제를 자주 만납니다. 대부분은 오류 메시지를 그대로 Claude Code에 붙여넣으면 해결되지만, 흔한 것들은 원인을 알아 두면 좋습니다.

참고

컨테이너 · 이미지 정리 명령 실습을 반복하면 안 쓰는 컨테이너와 이미지가 쌓입니다. 아래로 정리할 수 있습니다(무엇을 지우는지 확인하고 쓰세요). - docker ps : 실행 중인 컨테이너 목록 - docker compose down : compose로 띄운 것들 정리 - docker system prune : 안 쓰는 컨테이너 · 이미지 등을 한꺼번에 정리

[확인] 7장 & 1부 체크리스트

여기까지 됐는지 확인해 보세요. 하나라도 안 됐다면 해당 절로 돌아가 다시 진행합니다.

수고했습니다. 1부를 마치며, 여러분은 서비스를 "어디서든 똑같이 돌아가는 상자"에 담는 데 성공했습니다.