LabHub
배우기 러닝패스 코스

Building Images

Building a Dockerfile One Line at a Time

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

이 실습은 진짜 VM 에서 돕니다

이 상자는 파드가 아니라 KubeVirt 가 띄운 가상머신입니다. 리눅스 커널이 따로 돌고 systemd 가 실제로 서비스를 관리하며, docker 는 흉내가 아니라 진짜 도커 엔진입니다. docker run 으로 띄운 컨테이너는 실제로 프로세스가 되고 docker execdocker logs 도 그대로 동작합니다.

예전에는 이 실습이 파드 안에서 돌았습니다. 커널 권한을 전부 내려놓은 상자라 컨테이너를 띄우는 단계가 막혀 있었고, 그래서 이미지 아카이브를 직접 풀어 보는 우회로 배웠습니다. 이제 우회가 필요 없습니다.

알아 둘 것이 둘 있습니다.

목표

Dockerfile 지시어를 하나씩 추가하면서 각각이 이미지의 어느 부분을 바꾸는지 inspect 로 확인하고, 마지막에 리뷰 체크리스트를 통과하는 파일을 만듭니다.

왜 중요한가

Dockerfile 은 설정 파일처럼 생겼지만 실제로는 순서가 의미를 가지는 빌드 스크립트입니다. 같은 지시어라도 위치에 따라 레이어가 늘고, 캐시가 깨지고, 시크릿이 박제됩니다. 이 실습은 지시어를 외우는 것이 아니라 "이 줄이 레이어를 만드는가, 설정을 새기는가"를 매번 구분하는 습관을 들이는 것이 목적입니다. 그 구분 하나로 크기 문제와 보안 문제의 대부분이 예방됩니다.

단계

각 단계마다 새 태그로 빌드해서 앞 단계의 결과도 남겨 둡니다.

  1. /root/build1 을 만들고 /root/build1/Dockerfile 의 첫 줄을 FROM alpine:3.20 으로 작성합니다.
  2. labhub/app:v1 로 빌드합니다.
  3. /root/build1/app.sh 를 만들어 app-running 을 출력하게 하고, Dockerfile 에 WORKDIR /appCOPY app.sh /app/ 을 추가해 labhub/app:v2 로 빌드합니다.
  4. CMDJSON 배열 형식으로 추가해 app.sh 가 실행되게 하고 labhub/app:v3 로 빌드합니다. 실행하면 app-running 이 나와야 합니다.
  5. ENV APP_ENV=prodARG VERSION 을 추가하고, ARG 로 받은 값을 LABEL app.version 에 새깁니다. --build-arg VERSION=2.1.0 으로 labhub/app:v4 를 빌드합니다.
  6. ENTRYPOINT 를 배열 형식으로 두고 CMD ["default-arg"] 를 기본값으로 두어, 인자 없이 실행하면 default-arg 가, override-arg 를 주면 override-arg 가 출력되게 한 뒤 labhub/app:v5 로 빌드합니다.
  7. LABEL org.opencontainers.image.title=labhub-appEXPOSE 8080 을 추가해 labhub/app:v6 로 빌드합니다.
  8. 최종 /root/build1/Dockerfile 이 아래 다섯 항목을 모두 만족하게 다듬고 labhub/app:v7 로 빌드합니다.
    • FROM 에 태그가 고정되어 있고 latest 가 아니다
    • WORKDIR 이 첫 COPY 보다 에 있다
    • ENTRYPOINT 또는 CMD 가 JSON 배열이다
    • ENV/ARG 이름에 TOKEN·SECRET·PASSWORD·API_KEY 가 들어가지 않는다

참고

베이스 이미지 고정하기

/root/build1 을 만들고 /root/build1/Dockerfile 의 첫 줄을 FROM alpine:3.20 으로 작성합니다.

FROM 에 태그를 명시하세요. latest 는 어제 빌드와 오늘 빌드가 달라지게 만듭니다.

첫 빌드

labhub/app:v1 로 빌드합니다.

빌드 컨텍스트는 Dockerfile 이 있는 디렉터리를 지정합니다. -t 로 이름을 붙이지 않으면 나중에 찾기 어렵습니다.

작업 디렉터리와 파일 복사

/root/build1/app.sh 를 만들어 app-running 을 출력하게 하고, Dockerfile 에 WORKDIR /appCOPY app.sh /app/ 을 추가해 labhub/app:v2 로 빌드합니다.

WORKDIR 은 이미지 설정(Config.WorkingDir)에 새겨지고, COPY 는 레이어를 만듭니다. 두 지시어의 순서가 상대 경로의 의미를 정합니다.

기본 명령 지정하기

CMDJSON 배열 형식으로 추가해 app.sh 가 실행되게 하고 labhub/app:v3 로 빌드합니다. 실행하면 app-running 이 나와야 합니다.

셸 형식으로 쓰면 /bin/sh -c 로 감싸져 PID 1 이 셸이 됩니다. 배열 형식이 왜 필요한지는 앞 코스에서 봤습니다.

빌드 인자와 환경변수의 차이

ENV APP_ENV=prodARG VERSION 을 추가하고, ARG 로 받은 값을 LABEL app.version 에 새깁니다. --build-arg VERSION=2.1.0 으로 labhub/app:v4 를 빌드합니다.

ARG 는 빌드하는 동안만 살고 ENV 는 이미지에 남습니다. 빌드 인자로 받은 값을 이미지에 남기려면 LABEL 로 새기세요.

ENTRYPOINT 와 CMD 조합

ENTRYPOINT 를 배열 형식으로 두고 CMD ["default-arg"] 를 기본값으로 두어, 인자 없이 실행하면 default-arg 가, override-arg 를 주면 override-arg 가 출력되게 한 뒤 labhub/app:v5 로 빌드합니다.

ENTRYPOINT 는 고정되고 CMD 는 실행 시 인자로 교체됩니다. 둘 다 배열 형식으로 쓰세요.

표준 라벨과 포트 선언

LABEL org.opencontainers.image.title=labhub-appEXPOSE 8080 을 추가해 labhub/app:v6 로 빌드합니다.

OCI 표준 라벨 키는 org.opencontainers.image. 로 시작합니다. EXPOSE 는 포트를 여는 것이 아니라 문서화하는 지시어입니다.

리뷰 체크리스트 통과시키기

최종 /root/build1/Dockerfile 이 아래 다섯 항목을 모두 만족하게 다듬고 labhub/app:v7 로 빌드합니다.

지금까지의 Dockerfile 을 다섯 항목에 맞춰 다듬으세요. 채점은 파일 내용과 빌드 결과를 함께 봅니다.