티스토리 뷰

Docker

[Docker] Dockerfile 분석해보기

onlog writer 2023. 5. 23. 22:11

 

Dockerfile 

Dockerfile은 Docker 이미지를 빌드하는 데 사용되는 텍스트 파일입니다. Dockerfile을 사용하면 이미지의 구성을 정의하고 이미지를 빌드하는 데 필요한 명령을 지정할 수 있습니다. Dockerfile을 사용하면 이미지를 빌드하는 프로세스를 자동화할 수 있으며, 이미지를 빌드하는 데 필요한 명령을 기억할 필요가 없습니다.

 

Dockerfile을 사용하려면 다음 단계를 수행합니다.

  1. Dockerfile을 만듭니다. Dockerfile은 간단한 텍스트 파일이며, Docker 이미지를 생성하는 데 필요한 명령을 포함합니다.
  2. Dockerfile을 빌드합니다. Dockerfile을 빌드하면 Docker 이미지가 생성됩니다.
  3. Docker 이미지를 실행합니다. Docker 이미지를 실행하면 Docker 컨테이너가 생성됩니다. Docker 컨테이너는 Docker 이미지에 포함된 애플리케이션을 실행합니다.

Dockerfile은 애플리케이션을 배포하는 데 매우 유용한 도구이며, 애플리케이션을 배포하는 프로세스를 자동화하고 애플리케이션을 다른 환경에서 일관되게 실행할 수 있습니다.

 

 

 

◎ 전체 Dockerfile

#!/bin/sh
DATASOURCE_URL=$1
DATASOURCE_USERNAME=$2
DATASOURCE_PASSWORD=$3
JWT_SECRET=$4
PORT=$5
NAME=$6
VERSION=$7

if [ $# != 7 ]; then
  echo "파라미터를 확인해주세요."
  echo "DATASOURCE_URL:$1"
  echo "DATASOURCE_USERNAME:$2"
  echo "DATASOURCE_PASSWORD:$3"
  echo "JWT_SECRET:$4"
  echo "ACCESS_PORT:$5"
  echo "IMAGE_NAME:$6"
  echo "IMAGE_VERSION:$7"
  exit
fi

CONTAINER=$(docker ps -aq --filter "name=$NAME")

if [ -n "$CONTAINER" ]; then
  echo "컨테이너 종료"

  docker stop $CONTAINER

  echo "컨테이너 삭제"

  docker rm $CONTAINER
fi

IMAGE=$(docker images --filter=reference="$NAME" -q)

if [ -n "$IMAGE" ]; then
  echo "이미지 삭제"

  docker rmi $IMAGE
fi

USING_PORT_ID=$(docker ps -aq --filter "expose=$PORT")

if [ -n "$USING_PORT_ID" ]; then
  echo "포트번호 $PORT 컨테이너 종료"

  docker stop $USING_PORT_ID

  echo "포트번호 $PORT 컨테이너 삭제"

  docker rm $USING_PORT_ID
fi

echo "git pull start." &&
  git pull &&
  echo "git pull done." &&
  echo "docker image build" &&
  docker build -t $NAME:$VERSION . &&
  echo "docker image build done." &&
  echo "docker container run" &&
  docker run --name $NAME -p $PORT:8080 -e SPRING_DATASOURCE_URL=$DATASOURCE_URL -e SPRING_DATASOURCE_PASSWORD=$DATASOURCE_PASSWORD -e SPRING_DATASOURCE_USERNAME=$DATASOURCE_USERNAME -e JWT_SECRET=$JWT_SECRET $NAME:$VERSION

 

 

 

코드 분석해보기

#!/bin/sh // 프로세스를 실행하는 프로그램을 지정하는 의미

스크립트가 '/bin/sh' 쉘을 사용하여 실행되어야 함을 나타냅니다. '/bin/sh' 쉘은 유닉스 계열 운영 체제에서 기본 쉘입니다. '#!/bin/sh' 코드는 스크립트의 첫 번째 줄에 있어야 하며, '!' 기호는 스크립트가 쉘을 사용하여 실행되어야 함을 나타내고, 'bin/sh' 문자열은 스크립트가 실행되어야 할 쉘을 지정합니다.

 

  • # : 숫자 혹은 위치
  • ! : 전체 혹은 전부
  • / : 디렉토리의 경로
  • bin : bin이라는 폴더(혹은 디렉토리)는 binary 코드들의 폴더를 의미합니다.
    리눅스는 기존 OS와는 달라서 모든 실행파일이 2진코드로 이루어져있고, 윈도우같은 경우 ProgramFiles라는 폴더와 같습니다.
  • sh : SHELL의 종류, 리눅스에서 echo $SHELL 치면 나오는 프로그램입니다.
    기본적으로 sh, ash, bash, zsh 등이 있습니다. 윗줄의 $SHELL이라는 의미는 리눅스에는 환경설정 파일에 모든 변수가 저장되어 있다는 의미이고 그 변수명을 호출하면 어디서든 그 변수에 저장된 명령어, 혹은 프로그램을 실행할 수 있다는 것입니다.
    즉, $는 변수를 호출겠다는 의미고, SHELL이라는 변수명에 들어있는 걸 echo라는 명령어로 사용자에게 출력하겠다는 의미입니다.

 

 

 

DATASOURCE_URL=$1
DATASOURCE_USERNAME=$2
DATASOURCE_PASSWORD=$3
JWT_SECRET=$4
PORT=$5
NAME=$6
VERSION=$7

이 코드는 스크립트가 시작될 때 파라미터를 변수에 저장합니다.

이렇게 하면 스크립트 내에서 파라미터를 쉽게 사용할 수 있습니다.

 

위에서부터 차례대로

DATASOURCE_URL=$1 코드는 1번째 파라미터를 DATASOURCE_URL 변수에 저장합니다.

DATASOURCE_USERNAME=$2 코드는 2번째 파라미터를 DATASOURCE_USERNAME 변수에 저장합니다.

... (생략)

VERSION=$7 코드는 7번째 파라미터를 VERSION 변수에 저장합니다.

 

 

 

if [ $# != 7 ]; then             // 10번줄
  echo "파라미터를 확인해주세요."
  echo "DATASOURCE_URL:$1"
  echo "DATASOURCE_USERNAME:$2"
  echo "DATASOURCE_PASSWORD:$3"
  echo "JWT_SECRET:$4"
  echo "ACCESS_PORT:$5"
  echo "IMAGE_NAME:$6"
  echo "IMAGE_VERSION:$7"
  exit                           // 19번줄
fi                               // 20번줄

10번 줄은 자바에서 if문과 같은 것이고, $는 변수를 의미합니다. 

10번 줄에서 $(변수)의 #(숫자, 혹은 갯수)가 != 부등연산자(와 같지 않을 경우) 7과 같지 않을 경우 then (그러면) 11번부터 18번까지 출력해주세요.

그리고 19번의 종료를 통해 statement(명령문)을 나가주세요.

20번 줄은 프로세스를 종료해주세요.

 

위 코드는 7개의 파라미터가 전달되지 않으면 "파라미터를 확인해주세요." 라는 메시지를 출력하고 종료하는 코드다.

  • if 명령은 조건이 참일 때 실행되는 코드를 지정합니다.
  • [ $# != 7 ] 명령은 전달된 파라미터의 개수가 7개가 아닌지 확인합니다.
  • echo 명령은 주어진 문자열을 출력합니다.
  • exit 명령은 프로그램을 종료합니다.

 

 

 

CONTAINER=$(docker ps -aq --filter "name=$NAME")

위 코드는 CONTAINER 변수에 실행 중인 Docker 컨테이너 목록에서 NAME 변수에 지정된 이름을 가진 Docker 컨테이너의 ID를 저장합니다.

 

  • docker ps 명령은 Docker 컨테이너 목록을 출력합니다.
  • -aq 옵션은 실행 중인 Docker 컨테이너만 출력합니다.
  • --filter 옵션은 Docker 컨테이너를 필터링합니다. 그 이후의 문자열 조건에 해당하는 것만 걸러서 앞의 명령을 실행하겠다는 것
  • name=$NAME 옵션은 NAME 변수에 지정된 이름을 가진 Docker 컨테이너만 출력합니다.

 

 

 

if [ -n "$CONTAINER" ]; then
  echo "컨테이너 종료"

  docker stop $CONTAINER

  echo "컨테이너 삭제"

  docker rm $CONTAINER
fi

위 코드는 CONTAINER 변수가 빈 문자열이 아닌 경우 docker stop $CONTAINER 명령과 docker rm $CONTAINER 명령을 실행하여 Docker 컨테이너가 실행 중인 경우 컨테이너를 중지하고 삭제합니다.

  • docker images 명령은 Docker 이미지 목록을 출력합니다.
  • --filter 옵션은 Docker 이미지를 필터링합니다.
  • reference=$NAME 옵션은 NAME 변수에 지정된 이름을 가진 Docker 이미지만 출력합니다.
  • -q 옵션은 Docker 이미지 ID만 출력합니다.

 

 

 

IMAGE=$(docker images --filter=reference="$NAME" -q)

위 코드는 NAME 변수에 지정된 이름을 가진 Docker 이미지의 ID를 저장합니다.

  • docker images 명령은 Docker 이미지 목록을 출력합니다.
  • --filter 옵션은 Docker 이미지를 필터링합니다.
  • reference=$NAME 옵션은 NAME 변수에 지정된 이름을 가진 Docker 이미지만 출력합니다.
  • -q 옵션은 Docker 이미지 ID만 출력합니다.

 

 

 

if [ -n "$IMAGE" ]; then
  echo "이미지 삭제"

  docker rmi $IMAGE
fi

위 코드는 IMAGE 변수가 빈 문자열이 아닌 경우 docker rmi $IMAGE 명령을 실행하여 Docker 이미지가 존재하는 경우 이미지를 삭제합니다.

  • if 명령은 조건이 참일 때 실행되는 코드를 지정합니다.
  • [ -n "$IMAGE" ] 명령은 IMAGE 변수가 빈 문자열이 아닌지 확인합니다.
  • echo 명령은 주어진 문자열을 출력합니다.
  • docker rmi 명령은 Docker 이미지를 삭제합니다.

 

 

 

USING_PORT_ID=$(docker ps -aq --filter "expose=$PORT")

위 코드는 USING_PORT_ID 변수에 PORT 변수에 지정된 포트를 노출하는 Docker 컨테이너의 ID를 저장합니다.

 

  • docker ps 명령은 실행 중인 Docker 컨테이너 목록을 출력합니다.
  • -a 옵션은 모든 Docker 컨테이너를 출력합니다.
  • -q 옵션은 Docker 컨테이너 ID만 출력합니다.
  • --filter 옵션은 Docker 컨테이너를 필터링합니다.
  • expose=$PORT 옵션은 PORT 변수에 지정된 포트를 노출하는 Docker 컨테이너만 출력합니다.

 

 

 

if [ -n "$USING_PORT_ID" ]; then
  echo "포트번호 $PORT 컨테이너 종료"

  docker stop $USING_PORT_ID

  echo "포트번호 $PORT 컨테이너 삭제"

  docker rm $USING_PORT_ID
fi

이 코드는 USING_PORT_ID라는 변수가 정의되어 있고, 그 변수의 값이 비어 있지 않은 경우에만 실행됩니다.

코드가 실행되면, 먼저 포트번호 $PORT 컨테이너 종료라는 메시지를 출력합니다.

그런 다음, docker stop $USING_PORT_ID 명령을 사용하여 포트번호 PORT의 컨테이너를 중지합니다.

마지막으로, docker rm $USING_PORT_ID 명령을 사용하여 포트번호 PORT의 컨테이너를 삭제합니다.

이 코드는 포트번호 PORT의 컨테이너를 중지하고 삭제하는 데 사용됩니다.

 

 

 

echo "git pull start." &&               // 메시지 "git pull start."을 출력합니다.
  git pull &&                           // 원격 저장소에서 최신 변경 사항을 가져오기 위해 git pull 명령을 실행합니다.
  echo "git pull done." &&              // 메시지 "git pull done."을 출력합니다.
  echo "docker image build" &&          // 메시지 "docker image build"을 출력합니다.
  docker build -t $NAME:$VERSION . &&   // 이름 $NAME과 버전 $VERSION으로 Docker 이미지를 빌드합니다. .은 Docker가 현재 디렉토리에서 이미지를 빌드하라는 지시입니다.
  echo "docker image build done." &&    // 메시지 "docker image build done."을 출력합니다.
  echo "docker container run" &&        // 메시지 "docker container run"을 출력합니다.
docker run --name $NAME -p $PORT:8080 -e 
SPRING_DATASOURCE_URL=$DATASOURCE_URL -e 
SPRING_DATASOURCE_PASSWORD=$DATASOURCE_PASSWORD -e 
SPRING_DATASOURCE_USERNAME=$DATASOURCE_USERNAME -e 
JWT_SECRET=$JWT_SECRET $NAME:$VERSION

 

이름 $NAME으로 Docker 컨테이너를 실행합니다.

-p $PORT:8080 옵션은 Docker가 호스트 머신의 포트 8080을 컨테이너의 포트 PORT에 매핑하도록 지시합니다.

-e 옵션은 환경 변수를 컨테이너에 전달합니다.

$NAME:$VERSION은 Docker가 이름 $NAME과 버전 $VERSION의 이미지를 사용하도록 지시합니다.

 

 

 

Dockerfile의 수행

1. 원격 저장소에서 최신 변경 사항을 가져옵니다.

2. Docker 이미지를 빌드합니다.

3. Docker 컨테이너를 실행합니다.

Docker 이미지는 Docker 컨테이너를 실행하기 위한 모든 종속성을 포함하는 가벼운 가상화 환경입니다.

Docker 컨테이너는 Docker 이미지를 기반으로 생성되며, Docker 이미지의 종속성을 사용하여 실행됩니다.

 

 

 

'Docker' 카테고리의 다른 글

[Docker] docker 설치하는 방법  (0) 2023.04.07
[Build] Docker 빌드 중 CPU 이슈  (0) 2023.03.14
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함