[Docker] Dockerfile 명령어

Damongsanga·2024년 3월 5일
0
post-thumbnail

Dockerfile로 이미지를 관리하는 과정에서 비슷한 역할을 하는 명령어가 여럿 있다 보니 해당 기능에 어떤 명령어를 써야 하는지 어려움이 있었다. 이를 해결하기 위해 Dockerfile에 사용되는 명령어를 정리해보았다.

Dockerfile이란?

  • 완성된 이미지를 만들기 위한 작업을 기록한 파일

    • 도커는 위와 같은 일련의 과정을 손쉽게 기록하고 수행할 수 있는 docker build 명령어를 제공

    • 완성된 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 추가해야 하는 소스코드, 실행해야 하는 명령어와 쉘 스크립트 등을 하나의 파일에 기록해두면, 도커는 이 파일을 읽어서 컨테이너에서 작업을 수행한 뒤 이미지로 만듦

    • 생성한 이미지를 도커 허브(Docker Hub) 등을 통해 배포할 때, 이미지 자체를 배포하는 대신 이미지를 생성하는 방법을 기록해 놓은 Dockerfile을 배포가능

  • 왜 dockerfile을 사용해야 할까?

    • 어플리케이션에 필요한 패키지 설치 등을 명확히 함
    • 이미지 생성을 자동화하여 배포가 용이
    • 버전 관리 가능

Dockerfile 예시

  • jenkins 이미지를 생성하는 Dockerfile
FROM jenkins/jenkins:lts

USER root

COPY install_docker.sh /install_docker.sh
RUN chmod +x /install_docker.sh
RUN /install_docker.sh

RUN usermod -aG docker jenkins
RUN setfacl -Rm d:g:docker:rwx,g:docker:rwx /var/run/

USER jenkins
  • nodeJS 이미지를 생성하는 Dockerfile
#
# nodejs-server
#
# build:
#   docker build --force-rm -t nodejs-server .
# run:
#   docker run --rm -it --name nodejs-server nodejs-server
#

FROM node:16
LABEL maintainer="Seunghwan Seo <seosh817@naver.com>"
LABEL description="Seunghwan's Node.js server"

# Create app directory
WORKDIR /app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ] # 쉘에서 node server.js 명령어를 실행

Dockerfile 명령어

  • FROM : 생성할 이미지의 베이스가 될 이미지를 결정

  • LABEL : 이미지의 메타데이터를 설정 (key-value 형태로 설정)

    • docker inspect 명령어로 메타데이터 확인 가능
  • WORKDIR : 명령어를 실행할 디렉토리를 지정하는 명령어

    • linux cd와 동일하다
  • EXPOSE : Dockerfile의 빌드로 생성된 이미지에서 노출할 포트를 지정하는 명령어

    • 이 명령어 만으로 포트가 호스트의 포트와 바인딩하는 것은 아니다
    • 단지 해당 이미지를 사용하는 사용자에게 해당 포트를 사용한다고 문서화하는 목적을 가지는 것 뿐
    • 실제로 publish 하고 싶으면 docker run -P (대문자임!!) 옵션으로 포트 지정해줘야함
    • -P 옵션 -> 이미지에 설정된 EXPOSE의 모든 포트를 호스트에 연결하도록 설정
  • VOLUME : 컨테이너는 영구 데이터를 저장하기 적합하지 않음. 따라서 영구 저장이 필요한 데이터는 컨테이너 밖에 스토리지에 저장하기 위해 docker 호스트 머신상에 볼륨 마운트 하거나 공유 스토리지를 볼륨 마운트 함

    • 컨테이너가 삭제되어도 데이터는 유지됨

      VOLUME ["/마운트 포인트"]
      VOLUME /data # 컨테이너 내부에 /data 디렉토리 생성되며 호스트 머신의 파일 시스템과 연동
      docker run -v /host/directory:/container/directory my_image

COPY vs ADD

**COPY, ADD 모두 파일을 디렉토리에 복사하는 데에 사용된다.

  • COPY : 현재 디렉토리 경로의 모든 파일과 디렉토리를 해당 디렉토리에 디렉토리에다가 모두 복사하는 명령어.

    • “복사” 만 처리한다
    • COPY <호스트 운영체제 경로> <도커 이미지 상에서 경로>
  • ADD: COPY와 유사하지만, 몇 가지 추가 기능을 제공

    • ADD는 URL을 통해 “파일을 다운로드” & 압축 파일을 자동으로 “압축 해제”
    • 명령어 입력 방법은 COPY와 동일하다 ( ADD <호스트 운영체제 경로> <도커 이미지 상에서 경로> )

RUN vs CMD vs ENTRYPOINT

RUN, CMD, ENTRYPOINT는 모두 명령을 실행하는데 사용된다.

  1. RUN: Dockerfile의 RUN 명령은 이미지를 빌드할 때 실행되는 명령. RUN 명령은 이미지를 구축하는 단계에서 파일을 복사하고, 의존성을 설치하고, 빌드 등을 수행하는데 사용된다. 이 명령은 이미지를 구성할 때만 사용되며, 컨테이너가 시작될 때는 실행되지 않는다.

  2. CMD : CMD 명령어는 컨테이너가 실행될 때 실행되는 명령어 또는 명령어 리스트를 정의된다. Dockerfile에서 한 번만 사용할 수 있으며, 동일한 Dockerfile 내에 여러 개의 CMD가 있을 경우 가장 마지막에 나오는 것이 적용된다.

  3. ENTRYPOINT: Dockerfile의 ENTRYPOINT컨테이너가 시작될 때 실행되는 명령을 지정. 즉, 컨테이너가 시작될 때마다 해당 명령이 실행된다. 이것은 컨테이너를 실행할 때마다 실행되는 실행 파일이나 스크립트를 지정하는 데 사용된다. CMD 명령어와 함께 사용될 수 있다.

  • RUN : 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행

    • 단, Dockerfile을 이미지로 빌드하는 과정에서는 별도의 입력이 불가능하기 때문에 apt-get install apache2 명령어에서 설치할 것인지를 선택하는 Y/N 물음에 대해 Yes로 설정해야 한다
      apt-get install apache2 -y
    • 첫 번째 형식 : RUN <명령어>
      • 쉘 형식으로 작성, 쉘에서 실행
      • Linux 기본값은 /bin/sh -c
    • 두 번째 형식 : RUN ["실행 가능한 파일", "param1", "param2"] (exec 형식)
  • CMD : CMD는 해당 이미지로 컨테이너를 실행할 때 어떤 명령어를 수행할 것인지를 결정하는 명령어

    • Dockerfile에서 한 번만 사용할 수 있다.
  • ENTRYPOINT : Docker 컨테이너가 시작될 때 실행되는 실행 가능한 파일이나 스크립트를 지정.executable은 컨테이너가 시작될 때 실행할 실행 파일이나 스크립트를 나타내고, param1, param2 등은 해당 실행 파일에 전달할 매개변수

    ENTRYPOINT ["executable", "param1", "param2"] 
    ENTRYPOINT ["java", "-jar", "myapp.jar"] # => java -jar myapp.jar

ENV vs ARG

  • ENV는 이미지 내에서 실행되는 컨테이너에서 사용 가능한 환경 변수를 정의

  • ARG는 빌드 중에만 사용되는 빌드 전용 변수를 정의

  • ENV: Dockerfile 내에서 사용할 환경 변수를 정의한다. ENV 명령어를 사용하여 이미지 내부에서 사용할 환경 변수를 설정할 수 있습니다. 이러한 환경 변수는 이미지 내에서 실행되는 컨테이너에서 사용할 수 있습니다.

    예를 들어, ENV를 사용하여 포트 번호를 설정할 수 있습니다.

    ENV PORT=8080 #[key]=[value]나 [key] [value] 형태로 정의

    이제 Docker 이미지를 실행할 때 포트 번호를 설정할 필요 없이, 이미지 내에서 $PORT 환경 변수를 사용하여 포트 번호를 참조할 수 있습니다.

  • ARG: Dockerfile 빌드 중에만 사용되는 빌드 전용 변수를 정의합니다. ARG 명령어를 사용하여 빌드 중에만 사용되는 인수(argument)를 정의할 수 있습니다. 빌드된 이미지에는 해당 변수가 포함되지 않습니다.

    예를 들어, 빌드 중에 환경을 지정할 수 있는 환경 변수를 설정할 때 사용할 수 있습니다.

    ARG ENVIRONMENT

    이제 Docker 빌드 명령어를 실행할 때 --build-arg 플래그를 사용하여 해당 인수를 전달할 수 있습니다.

    docker build --build-arg ENVIRONMENT=development .

    이렇게 하면 빌드 중에 ENVIRONMENT라는 변수가 전달되며, Dockerfile 내에서 사용할 수 있습니다.

참조

https://seosh817.tistory.com/381?category=1035901
https://yangtaeyoung.github.io/docs/docker/04.dockerfile/
https://tech.cloudmt.co.kr/2022/06/29/%EB%8F%84%EC%BB%A4%EC%99%80-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%9D%98-%EC%9D%B4%ED%95%B4-3-3-docker-image-dockerfile-docker-compose/

profile
향유하는 개발자

0개의 댓글