Docker 이미지를 직접 만들어보자

김민우·2022년 10월 1일
0

docker

목록 보기
3/5

도커 이미지를 도커 허브에 있던 것들만 가져오는 것 뿐만 아니라, 직접 도커 이미지를 만들어서 사용할 수도 있고 직접 만든 도커 이미지를 도커 허브에 올려서 공유할 수도 있다.

그렇다면, 어떻게 도커 이미지를 만들까?

도커 이미지를 생성하는 순서는 다음과 같다.

  1. Dockerfile 작성
  2. 도커 클라이언트에 Dockerfile 전달
  3. 도커 서버에 Dockerfile을 전달
  4. 이미지 생성

1. Docker File 만들기

도커 파일은 도커 이미지를 만들기 위한 설정 파일로, 컨테이너가 어떻게 행동해야 하는지에 대한 설정들을 정의한 파일이다.

도커 파일을 만드는 순서는 다음과 같다. 도커 이미지가 필요한 것이 무엇인지를 생각한 후에 파일에 정의를 해야한다.

  1. 베이스 이미지를 명시해준다. (파일 스냅샷에 해당)
  2. 추가적으로 필요한 파일을 다운 받기 위한 몇가지 명령어를 명시해준다. (파일 스냅샷에 해당)
  3. 컨테이너 시작시 실행 될 명령어를 명시해준다. (시작 시 실행 될 명령어에 해당)

베이스 이미지❓

  • 도커 이미지는 여러 개의 레이어(중간 단계의 이미지)로 되어 있다. 그 중에서 베이스 이미지는 이 이미지의 기반이 되는 부분이다.
  • 쉽게 생각하자면 Window, MacOS, Linux 등과 같은 OS라고 볼 수도 있다.

💡 이해를 돕기 위한 예시

우선, 목표는 hello라는 문구를 출력하는 이미지를 만들어보는 것이다.
예시 순서는 다음과 같다.

도커 이미지 만들기 순서

  1. 도커 파일을 만들 폴더 하나 만들기
  2. 도커 파일 폴더를 에디터를 이용해서 실행 (ex. VSCode...)
  3. dockerfile이라는 이름을 가진 파일 하나를 생성한다.
  4. 파일에 어떻게 진행해 나갈지에 대한 기본적인 토대를 명시한다.

기본적인 토대를 살펴보자면 다음과 같다.

각각의 명령어를 조금 더 자세하게 살펴보자.
우선, FROM, RUN, CMD 등은 도커 서버에게 행동할 것을 알려주는 것이다.

  • FROM : 이미지 생성시 기반이 되는 이미지 레이어이다.
    - <이미지 이름> : <태그> 형식으로 작성하며, 태그를 안붙이면 자동적으로 가장 최신것으로 다운 받는다. ex. ubuntu:14.04

  • RUN : 도커 이미지가 생성되기 전에 수행할 쉘 명령어이다.

  • CMD : 컨테이너가 시작되었을 때 실행할 실행 파일 또는 셸 스크립트이다. 해당 명령어는 Dockerfile 내에서 한 번만 쓸 수 있다.

도커 이미지 만들기 순서

  1. 베이스 이미지부터 실제 값으로 추가해주기
  2. 베이스 이미지는 ubuntu나 centos를 사용해도 되지만, 지금 하려는 예시는 hello를 출력하는 작은 기능이기에 사이즈가 작은 alpine 베이스 이미지를 이용한다.
  3. hello 문자를 출력하기 위해 echo를 사용해야 하지만, 이미 alpine 안에 echo를 사용할 수 있는 파일이 있으니 RUN 부분은 생략한다.
  4. 마지막으로 컨테이너 시작시 실행 할 명령어인 echo hello를 적어준다.

도커 파일을 완성하였다! 그렇다면 이제 이미지는 어떻게 만들어야 할까?

2. 도커 파일로 도커 이미지 만들기

도커 파일에 입력된 것들이 도커 클라이언트로 전달하고 도커 서버가 인식하게 만들어야 한다.
그렇게 하기 위해서 docker build ./ or docker build .를 사용한다.

  • Build 명령어
    Build 명령어는 해당 디렉토리 내에서 dockerfile이라는 파일을 찾아서 도커 클라이언트에 전달시켜준다.
    docker build 뒤에 ./ .는 둘 다 현재 디렉토리를 가리킨다.

이제 dockerfile이 있는 디렉토리에서 터미널을 실행 후, docker build ./를 입력해보자! (vscode 툴 안에 built-in 된 터미널을 사용해도 된다.)

그런데 뭔가 출력 결과가 이상하다. 원래라면 아래와 같이 출력되어야 한다.

찾아 보니 강의 영상의 도커 버전과 현재 내가 사용하고 있는 도커 버전이 달라서 빌드 로그가 조금 다른듯 하다.
원인으로는 최신 버전의 buildkit 이라는 녀석이 이전 버전의 도커 엔진에서 제공되는 기능을 대체하여 생긴 현상이라고 한다.

여러 가지 해결책이 존재하지만, buildkit을 disable하는 방식으로 해결하였다.


docker desktop -> settings -> docker engine의 buildkit을 false로 바꿔주고 다시 실행해보았다.

다시 정상적으로 출력된 것을 볼 수 있다. 빨간 밑줄이 새로 생성된 컨테이너의 ID이다.
그런데 출력 내용을 자세히 보면 Removing intermediate container 94e06c476ebe라고 적힌 것을 볼 수 있다.
즉, 중간(임시) 컨테이너를 지워준다는 것인데... 왜 임시 컨테이너를 생성하고, 삭제하는 일을 만드는걸까?
순서를 다시 한번 정리하자면 다음과 같다.

  1. Alpine 이미지를 가져온다 (9c6f07244728)
  2. 임시 컨테이너를 생성한다 (94e06c476ebe)
    이때, 임시 컨테이너의 하드 디스크에 alpine 이미지가 가지고 있는 파일 스냅샷을 추가한다.
  3. echo hello 명령어를 임시 컨테이너에 넣어줌으로써 임시 컨테이너를 완성한다.
  4. 임시 컨테이너로 새로운 이미지(2e547471893f)를 만든 후에 이제 임시 컨테이너가 불필요하므로 임시 컨테이너를 삭제한다.

결론을 정리하자면 다음과 같다.

베이스 이미지에서 다른 종속성이나 새로운 커맨드를 추가 할때는 임시 컨테이너를 만든 후 그 컨테이너를 토대로 새로운 이미지를 만든다.
이미지를 만들고 난 후에는 임시 컨테이너를 지워준다.

도커 이미지에 별명 붙이기

앞서 만든 도커를 사용해보자.

보다시피 아이디가 2e5474...처럼 길고 사용하기도 어렵다.
이때, docker build -t <나의 도커 아이디>/<저장소/프로젝트 이름>:latest . 커맨드를 이용하면 별명(태그)를 만들어줄 수 있다.

docker build -t minuet1215/hello:latest를 입력하니 위와 같은 결과를 얻을 수 있었다.

바뀐 이름으로 run을 수행할 시에 hello가 잘 뜬 것을 확인할 수 있다.

profile
Pay it forward.

0개의 댓글