Profile picture

[Docker] 이미지 생성 및 배포 - Docker Hub

JaehyoJJAng2022년 05월 13일

◾️ 이미지 생성 방법

Dockerfile을 본격적으로 사용하기 이전에 Dockerfile 없이 이미지를 생성하는 방법에 대해 학습해보자


  • -a(--author) : 이미지 배포자
  • -m {MESSAGE} : 커밋 메시지

nginx 컨테이너 생성하기

$ docker run -d -it --name nginx -p 80:80 nginx:latest

my_nginx:v1 이미지 생성하기

# docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
# nginx 컨테이너의 현재 상태를 my_nginx:v1 이미지로 생성
$ docker commit -a yshrim12 -m "First commit" nginx my_nginx:v1


◾️ 도커 이미지 생성

새로 만들 이미지의 변경사항은 아래와 같다

  • 파이썬 실행 환경에 최적화 되어있는 python3:3.8-slim-buster 이미지를 베이스 이미지로 사용
  • FLASK 라이브러리를 활용하여 / 루트 앤드포인트 접속 시 , Hello World 출력하는 코드 작성
  • Dockerfile 로 작성
  • 이미지 빌드 후, 해당 이미지 기반의 컨테이너 생성하고 git 설치
  • Dockerfile 내에서 바로 설치해도 되지만 테스트를 위해 아래 절차와 같이 진행
    • git 설치 완료 후 해당 이미지 commit
    • commit 된 이미지를 docker hub 에 배포하기

Dockerfile

FROM python:3.8-slim-buster

WORKDIR /app
COPY ./server.py .
COPY ./requirements.txt .

RUN pip install --upgrade pip
RUN pip install -r requirements.txt

CMD ["python3","server.py"]

파이썬 스크립트와 필수 라이브러리는 아래와 같다.

server.py

from flask import Flask

app : Flask = Flask(__name__)
@app.route('/')
def root()-> str:
    return "Hello,World!"
  
if __name__ == '__main__':
    app.run(host="0.0.0.0",port=80,debug=False)

requirements.txt

flask

▪️ 이미지 빌드

  • -t(--tag) : 이미지 이름 및 태그 지정
  • -f : Dockerfile 명시
    • 현재 경로에 Dockerfile이 있는 경우 해당 옵션은 안써도된다
$ docker build --tag yshrim12/hello-world:1.0 -f Dockerfile .

▪️ 컨테이너 생성

  • 컨테이너와 호스트OS간 80번 포트로 마주보게 지정
  • custom_flask 라는 이름의 컨테이너 생성
$ docker run -d -it --name custom_flask --rm yshrim12/hello-world:1.0

▪️ 컨테이너 접속

  • bash shell 모드로 컨테이너 내부로 접속
$ docker exec -it custom_flask bash

▪️ 변경사항 생성

  • 현재 생성된 custom_flask 컨테이너에 apt-get 업데이트
  • git 설치
$ apt-get update && apt-get install -y git

깃 설치 완료 되었으면 저장소 하나 불러오기

# 프로젝트 폴더 생성
mkdir projects 

# 디렉토리 이동
cd projects # /app/projects

# 저장소 불러오기 
git clone https://github.com/teddylee777/bigdata-streamlit.git

▪️ 이미지 commit

원하는 변경사항을 모두 생성하였으니 현재 상태의 컨테이너를 새로운 이미지로 생성해보자.

commit 예시

docker commit <option> container <repository>:<tag>

이미지 커밋하기

docker commit -a "yshrim12" -m "Create Custom Flask Image" custom_flask custom_flask:1.0

image

즉, 위의 명령어는 custom_flask 라는 이름의 Docker 컨테이너를 custom_flask:1.0라는 이름과 태그를 가진 새로운 이미지로 만드는 명령어인 것이다.

옵션 살펴보기

  • -a : 이 옵션은 생성한 이미지를 만든 개발자의 이름이나 이메일 주소를 지정. 이 정보는 이미지의 메타데이터에 저장됨
  • -, : 이 옵션은 이미지를 생성할 때 추가할 메시지를 설정. 메시지는 커밋을 설명하며, 커밋 메시지는 이미지에 대한 변경 사항을 추적할 수 있는 중요한 정보임
  • custom_flask : 이미지로 만들 Docker 컨테이너의 이름. 해당 컨테이너는 이미지를 만들기 위한 원본 컨테이너임
  • custom_flask:1.0 : 생성된 새 이미지의 이름과 태그. ':' 를 사용하여 이름과 태그를 분리하고, 태그를 지정하지 않으면 기본값으로 latest 가 사용된다. 새 이미지는 이 이름과 태그를 사용하여 이미지 레포지토리에 푸시하거나 태그 변경이 가능함

▪️ 이미지를 파일로

  • -o ~/docker-images/custom_flask.tar : 저장될 파일의 이름과 경로 지정
    • 이 경우 ~/docker-images 경로에 custom_flask.tar 파일에 이미지가 저장된다.
  • custom_flask:1.0 : 저장할 Docker 이미지의 이름과 태그

Example

$ docker save -o [OUTPUT-FILE] IMAGE

언젠가 쓸 일이 있지 않을까?

위에서 만든 이미지를 압축 파일로 추출해보자

$ docker save -o ~/docker-images/custom_flask.tar custom_flask:1.0

도커 이미지 파일을 다시 도커 이미지로 불러오는 방법도 물론 존재

d$ ocker load -i ~/docker-images/custom_flask.tar

쓸 일이 있겠나 싶다.



◾️ docker hub로 배포하기

도커 허브에 접속해서 Create Repository 를 클릭

image

▪️ 이미지 복제

  • 이미 존재하고 있는 custom_flask:1.0 이미지를 기반으로 yshrim12/testrepo_flask:1.0 이미지를 생성
  • yshrim12/testrepo_flask:1.0 이미지는 이미 존재하던 이전 이미지(custom_flask:1.0)의 복제품임
  • 이전 이미지를 삭제하지 않음.그대로 남아있음

이미지 복제

$ docker tag custom_flask:1.0 yshrim12/testrepo_flask:1.0

이미지 목록 출력

docker images

REPOSITORY                          TAG         IMAGE ID       CREATED            SIZE
custom_flask:1.0                   latest      f0143cd8b801    1 minutes ago      60MB
yshrim12/testrepo_flask:1.0        latest      f0143cd8b801    1 minutes ago      60MB

image

▪️ 도커 허브 로그인

$ echo "${DOCKER_PASSWORD}" | docker login -u ${DOCKER_USER} --password-stdin
  • 도커 로그인 정보는 /<username>/.docker/config.json 파일에 저장된다

못찾겠으면 그냥 아래 커맨드로 찾으면 된다.

$ find / -name ".docker" -type d 2>/dev/null

▪️ 이미지 배포

$ docker push yshrim12/testrepo_flask:1.0

image

이제 docker hub 로 가서 정상적으로 배포가 되었는지 확인해보자

image


Loading script...