[Docker] Dockerfile(IaC) κ°œλ… 및 λͺ…λ Ήμ–΄, Dockerfile μ΅œμ ν™”

IaC (Infrastructure as Code, μ½”λ“œν˜• 인프라)κ°€ ν•„μš”ν•œ 이유

  • μ»€λ§¨λ“œ 기반의 인프라 ꡬ성 μ‹œ μ‚¬μš©μž μ‹€μˆ˜ λ“±μ˜ 인적 였λ₯˜ κ°€λŠ₯성이 λ†’μŒ.
  • μ„€μΉ˜ μˆœμ„œμ™€ μƒν˜Έ μ—°κ΄€μ„± 등을 κ³ λ €ν•˜μ—¬ 각쒅 λΌμ΄λΈŒλŸ¬λ¦¬μ™€ ν•¨κ»˜ λ³΅μž‘ν•œ λͺ…령어듀을 κ³ λ―Όν•˜κ²Œ λ˜λŠ”λ° μ½”λ“œν˜• μΈν”„λΌλ‘œ ν•΄κ²° κ°€λŠ₯.
  • μˆ˜μ •μ‚¬ν•­μ€ μ–Έμ œλ“  μ½”λ“œ 변경을 톡해 κ°€λŠ₯ν•˜λ‹€. λ”°λΌμ„œ 개발 업무 λͺ©μ μ„ μ΄λ£¨λŠ” κ²ƒμ—λ§Œ μ˜¨μ „νžˆ 집쀑할 수 μžˆλ‹€.
  • IaCλŠ” 탄λ ₯μ„±, ν™•μž₯μ„±, λ°˜λ³΅μ„±μ„ λΆ€μ—¬ν•˜κ²Œ λ˜μ–΄ λˆˆμ†‘μ΄ μ„œλ²„κ°€ μ•„λ‹Œ λ™μΌν•œ ν™˜κ²½μ„ λ³΄μœ ν•œ μ„œλ²„(μ»¨ν…Œμ΄λ„ˆ)λ₯Ό μˆ˜μ‹­~μˆ˜λ°±λŒ€λ₯Ό 운영, κ΄€λ¦¬ν•˜κ²Œ ν•΄μ€€λ‹€. 
    • λˆˆμ†‘μ΄ μ„œλ²„:  μ‹€μ œ 운영 ν™˜κ²½μ€ λ‹€μ–‘ν•œ μ„œλ²„λ₯Ό κ°–κ³  μžˆλ‹€. κ°œλ°œμ„œλ²„, ν…ŒμŠ€νŠΈμ„œλ²„, μš΄μ˜μ„œλ²„ 등이 μžˆλŠ”λ° μš΄μ˜μ„ ν•˜λ‹€λ³΄λ©΄ μ—¬λŸ¬κ°€μ§€ λ³€κ²½ 사항이 μžˆλ‹€. μ΄λ•Œ λ˜‘κ°™μ€ setup을 ν•œλ‹€κ³  해도 ν…ŒμŠ€νŠΈμ„œλ²„μ—μ„  되던게 μš΄μ˜μ„œλ²„μ—μ„  μ•ˆ λ˜κΈ°λ„ ν•˜λŠ” 상황이 μΌμ–΄λ‚˜κ²Œλœλ‹€. 이런 ν™˜κ²½μ„ λˆˆμ†‘μ΄ μ„œλ²„λΌκ³  ν•œλ‹€. 

 

κ·Έλ ‡λ‹€λ©΄ Dockerfileμ΄λž€ 뭘까

 

Dockerfile

  • Dockerfile은 Dockerμ—μ„œ λ™μž‘ν•˜λŠ” μ»¨ν…Œμ΄λ„ˆμ˜ ꡬ성 정보λ₯Ό ν”„λ‘œλΉ„μ €λ‹(Provisioning)ν•œ ν…μŠ€νŠΈ template νŒŒμΌμ΄λ‹€. 
    • ν”„λ‘œλΉ„μ €λ‹μ€ μ‚¬μš©μžμ˜ μš”κ΅¬μ— 맞게 μ‹œμŠ€ν…œ μžμ›μ„ ν• λ‹Ή, 배치, 배포해 λ‘μ—ˆλ‹€κ°€ ν•„μš” μ‹œ μ‹œμŠ€ν…œμ„ μ¦‰μ‹œ μ‚¬μš©ν•  수 μžˆλŠ” μƒνƒœλ‘œ 미리 μ€€λΉ„ν•΄ λ‘λŠ” 것
  • λ”°λΌμ„œ Dockerfile은 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 배포에 ν•„μš”ν•œ μ»¨ν…Œμ΄λ„ˆ 인프라λ₯Ό μ½”λ“œ ν˜•νƒœλ‘œ μ •μ˜ν•œ νŒŒμΌμ΄λ‹€. μ΄λŸ¬ν•œ κ°œλ…μ„ IaC, μ½”λ“œν˜• 인프라 라고 ν•œλ‹€.

 

Dockerfile λͺ…λ Ήμ–΄

FROM (Layer)

  • μƒμ„±ν•˜λ €λŠ” μ΄λ―Έμ§€μ˜ 베이슀 이미지 지정
  • 이미지λ₯Ό 선택할 땐 μž‘μ€ 크기의 이미지(slim)와 λ¦¬λˆ…μŠ€ 배포판이 μ•ŒνŒŒμΈ(alpine) 이미지λ₯Ό ꢌμž₯
  • νƒœκ·Έλ₯Ό 넣지 μ•ŠμœΌλ©΄ Latest둜 지정

 

MAINTAINER 

  • 이미지λ₯Ό λΉŒλ“œν•œ μž‘μ„±μž 이름과 이메일 μž‘μ„±

 

LABEL (Layer)

  • μ΄λ―Έμ§€μ˜ μž‘μ„± λͺ©μ μ΄λ‚˜ 정보 등을 μž‘μ„±
  • 이미지 관리에 도움

 

RUN (Layer)

  • μ„€μ •λœ κΈ°λ³Έ 이미지에 νŒ¨ν‚€μ§€ μ—…λ°μ΄νŠΈ, μ„€μΉ˜, μ‹€ν–‰ 등을 μž‘μ„±
  • RUN λͺ…λ Ήμ–΄μ˜ κ°œλ³„ 수λ₯Ό μ€„μ—¬μ„œ μ—¬λŸ¬ μ„€μΉ˜ λͺ…령을 μ—°κ²°ν•˜λ©΄ μ΄λ―Έμ§€μ˜ λ ˆμ΄μ–΄ 수λ₯Ό κ°μ†Œμ‹œν‚¬ 수 μžˆλ‹€.
RUN apt update && apt install -y nginx \
	git \
    vim \
    curl

 

CMD

  • μƒμ„±λœ 이미지λ₯Ό μ»¨ν…Œμ΄λ„ˆλ‘œ μ‹€ν–‰ν•  λ•Œ μ‹€ν–‰λ˜λŠ” λͺ…λ Ήμ–΄
  • μ—¬λŸ¬κ°œμ˜ CMDλ₯Ό μž‘μ„±ν•΄λ„ λ§ˆμ§€λ§‰ ν•˜λ‚˜λ§Œ μ²˜λ¦¬λœλ‹€. 
  • 즉, 이미지가 μ»¨ν…Œμ΄λ„ˆλ‘œ 싀행될 λ•Œ λ™μž‘
  • 정적인 이미지 ν™˜κ²½ -> 동적인 μ»¨ν…Œμ΄λ„ˆ ν™˜κ²½ 으둜 이동할 λ•Œ μ‚¬μš©

 

ENTRYPOINT

  • CMD와 λ§ˆμ°¬κ°€μ§€λ‘œ μƒμ„±λœ 이미지가 μ»¨ν…Œμ΄λ„ˆλ‘œ 싀행될 λ–„ μ‚¬μš©ν•˜μ§€λ§Œ, λ‹€λ₯Έ 점은 μ»¨ν…Œμ΄λ„ˆκ°€ 싀행될 λ•Œ λͺ…렁어 및 인자 값을 μ „λ‹¬ν•˜μ—¬ μ‹€ν–‰ν•œλ‹€.
  • ENTRYPOINTλŠ” CMD와 λ‹€λ₯΄κ²Œ μ—¬λŸ¬ 개 μ‹€ν–‰ κ°€λŠ₯

 

COPY (Layer)

  • 호슀트 ν™˜κ²½μ˜ 파일, 디렉터리λ₯Ό 이미지 μ•ˆμ— λ³΅μ‚¬ν•˜λŠ” 경우 μž‘μ„±
  • λ‹¨μˆœν•œ 볡사 μž‘μ—…λ§Œ 지원
  • 디렉토리 μ™ΈλΆ€μ˜ νŒŒμΌμ€ COPYν•  수 μ—†λ‹€.
  • ADD보닀 COPY ꢌμž₯

 

ENV (Layer)

  • 이미지 μ•ˆμ— 각쒅 ν™˜κ²½ λ³€μˆ˜λ₯Ό 지정해야 ν•˜λŠ” κ²½μš°κ°€ 많음
  • μ•„λž˜μ™€ 같이 μž‘μ„±ν•˜λ©΄ λœλ‹€.
ENV TZ=Asia/Seoul

 

EXPOSE

  • μ»¨ν…Œμ΄λ„ˆκ°€ 호슀트 λ„€νŠΈμ›Œν¬λ₯Ό 톡해 λ“€μ–΄μ˜€λŠ” νŠΈλž˜ν”½μ„ λ¦¬μŠ€λ‹ν•˜λŠ” ν¬νŠΈμ™€ ν”„λ‘œν† μ½œμ„ μ§€μ •ν•˜κΈ° μœ„ν•΄ μž‘μ„±

 

VOLUME

  • λ³Όλ₯¨μ„ 이미지 λΉŒλ“œμ— 미리 μ„€μ •ν•˜λŠ” 경우 μž‘μ„±

 

ARG

  • docker build μ‹œμ μ—μ„œ λ³€μˆ˜ 값을 μ „λ‹¬ν•˜κΈ° μœ„ν•΄ "--build-arg=인자"λ₯Ό μ •μ˜ν•˜μ—¬ μ‚¬μš©
  • λΉ„λ°€ ν‚€, 계정 λΉ„λ°€λ²ˆν˜Έ 같은 λ―Όκ°ν•œ 정보 μ‚¬μš© μ‹œ 이미지에 κ·ΈλŒ€λ‘œ μ‘΄μž¬ν•˜μ—¬ λ…ΈμΆœλ  μœ„ν—˜μ΄ μžˆμœΌλ―€λ‘œ μ΄λŸ¬ν•œ μ •λ³΄λŠ” μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. 

 

 

μ•„λž˜λŠ” JAVA μ• ν”Œλ¦¬μΌ€μ΄μ…˜ Dockerfile μ˜ˆμ‹œμ΄λ‹€.

FROM openjdk:11
ARG JAR_FILE=build/libs/app.jar
COPY ${JAR_FILE} ./app.jar
ENV TZ=Asia/Seoul
ENTRYPOINT ["java", "-jar", "./app.jar"]

 

 

 

Dockerfile μ΅œμ ν™”

μ™œ 도컀 νŒŒμΌμ„ μ΅œμ ν™”ν•΄μ•Ό ν• κΉŒ??

  • μ»¨ν…Œμ΄λ„ˆ μ„œλΉ„μŠ€λŠ” κ²½λŸ‰μ˜ 가상화 μ„œλΉ„μŠ€λ₯Ό λͺ©μ μœΌλ‘œ ν•œλ‹€.
  • Dockerμ—μ„œ μ œκ³΅λ˜λŠ” base imageλ“€ λ˜ν•œ 지ν–₯점에 ν•„μš”ν•œ ν”„λ‘œκ·Έλž¨, 라이브러리, μ‹€ν–‰νŒŒμΌ λ§Œμ„ λ³΄μœ ν•˜κ³  있음.
  • λΉ λ₯Έ μ»¨ν…Œμ΄λ„ˆ 배포λ₯Ό μœ„ν•΄ "μ΅œμ†Œν•œμ˜ μ„€μ •κ³Ό ꡬ성"을 ꢌμž₯ν•˜κ³  μžˆλ‹€.

 

μ΅œμ ν™” λ°©μ•ˆ

1. μ»¨ν…Œμ΄λ„ˆ μ΄λ―Έμ§€μ—μ„œ λΆˆν•„μš”ν•œ λ°”μ΄λ„ˆλ¦¬λ₯Ό λͺ¨λ‘ μ œκ±°ν•˜μ—¬ 이미지 크기λ₯Ό κ²½λŸ‰ν™”

  • μ„€μΉ˜λœ νŒ¨ν‚€μ§€ νŒŒμΌμ€ autoremove, cleanλ“±μ˜ λͺ…령을 톡해 μ œκ±°ν•˜λ©΄ κ²½λŸ‰ν™”μ— λ„μ›€λœλ‹€.

2. Dockerμ—μ„œ μ œκ³΅ν•˜λŠ” μ΅œμ†Œ κΈ°λ³Έ 이미지인 alpine linux λ˜λŠ” scratchλ₯Ό μ‚¬μš©ν•œλ‹€.

3. multi-strage-buildλ₯Ό μ‚¬μš©ν•˜μ—¬ μ΅œμ’… 이미지 크기λ₯Ό μ΅œμ†Œν™”

  • multi-stage-buildλŠ” μ—¬λŸ¬ 개의 base imageλ₯Ό μ‚¬μš©ν•œ docker build이닀.
  • FROM λͺ…λ Ήμ–΄κ°€ 2개 이상 μ‚¬μš©λ˜μ–΄ λΆ„λ¦¬λœ μž‘μ—… 곡간(stage)λ₯Ό 제곡
  • 첫 번째 stageμ—μ„œ μƒμ„±λœ μ‹€ν–‰νŒŒμΌ 등을 두 번째 stage에 제곡
  • λ§ˆμ§€λ§‰μ— μ‹€ν–‰λœ stage μž‘μ—…μ΄ Docker image둜 μ΅œμ’… μƒμ„±λ˜μ–΄ 이미지 크기가 κ°μ†Œν•œλ‹€.
  • wgetλ“±μ˜ λͺ…λ Ήμ–΄κ°€ λ³΄μ•ˆμ μΈ ν—ˆμ μ΄ μžˆλ‹€κ³  μ–˜κΈ°ν•˜λŠ”λ°, stage1μ—μ„œ 그런 μž‘μ—…λ“€μ„ μˆ˜ν–‰ν•˜κ³  stage2μ—μ„œ μ‚¬μš©ν•œλ‹€λ©΄ 이λ₯Ό μ˜ˆλ°©ν•  수 μžˆλ‹€.

4. Dockerfile μž‘μ„± μ‹œ μƒμ„±λ˜λŠ” Layer수 μ΅œμ ν™” 예둜 RUN μ‚¬μš© μ‹œ κ°€λŠ₯ν•˜λ©΄ λͺ…령을 κ²°ν•©(κ·Έλ£Ήν™”)ν•˜μ—¬ μ‚¬μš©

 

 

Dockerfile build 방법

docker build -t IMAGE_NAME:TAG [-f DOCKERFILE_NAME] DOCKERFILE_LOCATION

Docker build κ³Όμ •

Docker run κ³Όμ •