[Docker] 이미지 빌드 cli로 실행하기

강버섯·2022년 2월 24일
1

👉 Docker image?

Docker image는 docker에서 컨테이너 실행을 위해 필요한 모든 파일과 환경 설정들을 포함하고 있는 것을 의미한다.

  • image : 실행되지 않은 상태
  • container : image가 실행된 상태

👉 이미지 빌드

Docker의 이미지는 Dockerfile에 적힌 명세대로 생성이 된다.
Dockerfile의 구성/작성에 대해서는 이전에 가볍게 정리해보았었다. 👉 docker 이미지 빌드

Dockerfile로 이미지를 빌드할 때에는 한가지 base에 계속 빌드(single stage build)를 진행하거나 여러 단계로 base를 나누어 빌드(multi stage build)를 진행할 수 있다.

  • single stage build
    실행을 위한 package 파일 생성에 필요한 부가적인 것들을 설치와 package 파일 생성을 FROM에서 상속 받은 하나의 base image에 모두 진행한 뒤 docker 이미지로 생성해낸다.
  • multi stage build
    FROM에서 상속 받은 base image의 사본들을 생성해 단계별로 사용을 한 뒤, docker 이미지를 만들기 위한 base image에서는 깨끗한 환경에서 package 파일만이 존재할 수 있도록 만들어낸다.
    multi stage 방식으로 이미지를 빌드하면 용량이 작고 깨끗한 docker image를 생성할 수 있다.

multi stage build를 사용한 Dockerfile 예시👇

FROM python:3.7.7-alpine3.12 as base

# stage 1
WORKDIR /usr/src/app

# package build에 필요한 환경 설정
.
.
.

# stage 2
FROM base as builder

# package build에 필요한 dependency, library들 설치
.
.
.
 
# stage 3
FROM base as final

# package build

COPY --from=builder /venv /venv
COPY --from=builder /usr/src/app/dist .
COPY wsgi.py ./wsgi.py
COPY docker/entrypoint.sh ./entrypoint.sh

ENV PATH="/venv/bin:${PATH}"
RUN . /venv/bin/activate && pip install *.whl

EXPOSE 5000
ENTRYPOINT ["./entrypoint.sh"]

DockerFile를 작성하였다면, 다음과 같은 명령어를 통해 docker file로부터 docker image를 빌드해낼 수 있다.

# context directory : build를 시작하는 dir
# 생성하는 이미지에 tag를 붙이고 싶을 때 -t(tag option) 사용
# tag를 미지정할 경우 자동으로 "lastet"가 붙여짐
$> docker build [-t] <ImageName:TagName> <context directory>

$> docker build .

$> docker build -f <docker 파일 위치>

👉 빌드한 docker image push하기

Docker image는 registry라는 docker를 사용할 수 있도록하는 외부 저장소에 올려놓고 사용할 수 있다.
Registry에 docker image를 push 해두면 사용하고 싶을 때 언제든 가져다 사용할 수 있다.

✏️ Default

$> docker build를 통해 docker image를 빌드하면 기본적으로 docker.io(docker hub) 이름으로 host가 붙여있다고 생각한다.

✏️ AWS의 ECR

AWS에서는 ECR(Elastic Container Registry) 라는 별도의 registry를 제공한다.
AWS resource를 사용할 예정이라면 ECR를 사용하는 편이 더 편리할 것이다.

ECR에 docker image를 push하기 위해서는 ECR repo의 주소로 docker image에 이름을 붙여줘야한다.
ECR repo 주소는 {ecr host 주소}/{image 이름}이고, 이 때 사용하는 ECR의 host 주소{aws account}.dkr.ecr.{aws region}.amazonaws.com로 고정된다.
AWS account의 값은 AWS console을 통해 확인하거나 aws sts get-caller-identity | jq -r .Account 명령어를 통해 cli로 확인할 수도 있다.

✏️ ECR에 push 해보자!

  • AWS console을 이용해서 올리기
    AWS console에서 ECR로 들어가 직접 생성한 docker image를 업로드할 수 있다.
  • cmd에서 올리기
  1. aws repository 생성
$> aws ecr create-reposiotry --repository-name repo이름
  1. docker가 aws에 로그인
$> docker login --username AWS --password-stdin <ecr host 주소>

만약 aws의 username과 password를 모른다면 $> aws ecr get-login-password --region region이름 명령어를 통해 알아올 수 있다.

  1. docker push
$> docker push ${ecr repo uri}:${image tag}

👉 shell script 활용하기

위의 과정을 cmd에 하나씩 명령어를 쳐가며 진행을 해도 되지만, shell script로 과정을 작성해두고 script file만 실행시켜서 build 후 push까지 진행한다면 훨씬 간편할 것이다.

build.sh 👇

#!/bin/bash

# 항상 같은 dir에서 실행될 수 있도록 위치를 build를 시작할 위치로 옮겨줌
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )
PROJECT_ROOT=$SCRIPT_DIR
cd "${PROJECT_ROOT}"

AWS_REGION="aws region"
IMAGE_NAME="생성할 docker image 이름"
IMAGE_TAG="latest"

DOCKERCLI=docker
AWSCLI=aws
JQCLI=jq

# build를 진행할 때 필요한 명령어들이 설치되어있는지 여부 확인
# 없어서 error가 발생한다면 종료되도록 setting
set -e
command -v ${AWSCLI} > /dev/null 2>&1    || { echo >&2 'aws-cli not found'; exit 1; }
command -v ${DOCKERCLI} > /dev/null 2>&1 || { echo >&2 'docker not found'; exit 1; }
command -v ${JQCLI} > /dev/null 2>&1     || { echo >&2 'jq not found'; exit 1; }
# setting 해제
set +e

VERSION=$( poetry version -s )
AWS_ACCOUNT_ID=$( ${AWSCLI} sts get-caller-identity | ${JQCLI} -r .Account )	

ECR_HOST_NAME=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
REPO_URI=$ECR_HOST_NAME/$IMAGE_NAME

# 이미지 빌드
${DOCKERCLI} build -t ${IMAGE_NAME} . -f ./Dockerfile
# 빌드한 이미지에 tag 붙이기
# docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
${DOCKERCLI} tag "${IMAGE_NAME}:${IMAGE_TAG}" "${IMAGE_NAME}:${VERSION}"
${DOCKERCLI} tag "${IMAGE_NAME}:${IMAGE_TAG}" "${REPO_URI}:${VERSION}"
${DOCKERCLI} tag "${IMAGE_NAME}:${IMAGE_TAG}" "${REPO_URI}:${IMAGE_TAG}"

# docker가 aws 로그인
aws ecr get-login-password --region $AWS_REGION | \
    docker login --username AWS --password-stdin $ECR_HOST_NAME

# docker image push
${DOCKERCLI} push "${REPO_URI}:${VERSION}"
${DOCKERCLI} push "${REPO_URI}:${IMAGE_TAG}"

build.sh를 생성했다면 실행 권한을 추가하고,

$> chmod +x build.sh

실행시킨다.

$> ./build.sh
profile
무럭무럭 버섯농장

0개의 댓글