본문 바로가기

Container/생활코딩 Docker

[Docker] build와 Dockerfile로 나만의 이미지를 만들어보자

반응형

🔊 해당 포스팅은 이고잉님의 생활코딩 오픈튜토리얼의 Docker 입문 수업을 듣고 제 개인적으로 정리하는 목적하에 작성되는 포스팅입니다. 보다 자세한 강의는 여기를 참고해주세요.

 

저번 포스팅 말미에서 잠깐 소개한 build 명령어와 Dockerfile 파일로 내가 만든 컨테이너를 나만의 이미지로 만드는 방법에 대해 소개했었다. 이번 포스팅에서는 그것들에 대한 사용법을 좀 더 자세하게 알아보려고 한다.

 

Docker


그런데 저번 포스팅에서 내가 만든 컨테이너를 나만의 이미지로 생성하는 방법 중 하나로 commit 명령어에 대해 알아보았다. 그렇다면 build 명령어와 Dockerfile을 활용하는 방법과 무슨 차이가 있을까? 가시적인 가장 큰 차이점은 내가 만든 이미지가 어떤 과정 즉, 어떤 프로그램이 설치되고 어떤 언어들이 깔려있고 등등에 대한 이미지에 대한 정보를 알아볼 수 있느냐의 차이다. commit은 저번에도 알아보았다 시피 내가 만든 컨테이너를 단순히 결과물로서 이미지화 시키는 것이라는 면에서 이미지에 대한 정보를 기록하지 않은 채 컨테이너를 이미지화시키는 특징을 갖는다. 반면에 build와 Dockerfile을 활용하면 Dockerfile이라는 일종의 약속된 형식의 파일 안에 이미지에 대한 정보를 기록할 수 있다.

 

따라서 보통 commit은 마치 파일의 버전을 관리하는 git 처럼 버전관리 툴로 자주 사용하고 build 명령어, Dockerfile은 내가 만든 컨테이너를 다른 사람에게 공개하고 또는 내 자신이 알아볼 수 있도록 기록하기 위한 것이다. 결국 두 개 중 뭐가 좋고 나쁘다기 보다는 어떤 목적을 갖고 사용하느냐에 따라 차이점이 있다.

 

그렇다면 이제 본격적으로 build 명령어와 Dockerfile을 가지고 내가 만든 컨테이너를 나만의 이미지로 어떻게 만드는지 좀 더 세부적으로 살펴보자. 특히 Dockerfile 파일 내에 작성되는 내용이 일종의 명령어들이기 때문에 이를 파악하는 것이 가장 핵심적이다.


먼저 터미널에서 ubuntu:20.04 버전의 이미지를 pull 하고 컨테이너를 생성해 해당 컨테이너로 들어가보자. 명령어는 다음과 같다.

 

docker run --name [만들 컨테이너 이름] -it [pull시킬 이미지]

 

webserver1 이라는 컨테이너를 생성

 

그리고 해당 컨테이너에서 apt 프로그램(리눅스에서의 마치 앱스토어 같은 프로그램)을 업데이트 해주고 Python을 설치하면 내장되어 있는 웹서버를 활용하기 위해 Python3를 설치해보자. 터미널에서 입력할 명령어는 다음과 같다.

 

apt update && apt install python3

 

이제 Python3가 설치된 컨테이너를 commit 명령어를 활용해 webserver1-image 라는 이름(tag)으로 이미지화시켜보자. 터미널에서 입력할 commit 명령어는 다음과 같다.

 

docker commit [이미지화시킬 컨테이너이름] [생성할 이미지 repo]:[생성할 이미지 tag]

 

webserver1-python 이라는 이미지가 새로 생겼다.

 

방금까지 진행한 ubuntu 이미지를 pull 하고 컨테이너를 생성해 Python3를 설치한 후 commit을 활용해 이미지를 만든 것을 build 명령어와 Dockerfile 파일로 어떻게 똑같이 만들 수 있을까? 우선 Dockerfile 파일 속에 다음과 같이 내용을 작성해준다.

 

Dockerfile 파일 내용

 

위 내용을 해석하자면 ubuntu:20.04 라는 이미지를 pull 하고 컨테이너를 생성한 후 해당 컨테이너에 들어가 apt 프로그램을 업데이트하고 python3 프로그램을 설치하라는 의미이다. 위 Dockerfile을 build 명령어로 다음과 같이 이미지화 시켜준다.

 

docker build -t [새로 생성할 이미지 이름] [Dockerfile 디렉토리 경로];
docker run --name [새로 생성할 컨테이너 이름] -it [새로 생성한 이미지 이름]

 

위 명령어를 연속으로 입력시켜보고 새로 생성한 이미지에서 새롭게 생성된 컨테이너에 들어가 python을 쳐보면 기본적으로 python이 설치되어 있는 것을 볼 수 있다.

 

build 명령어와 Dockerfile을 활용해 commit으로 생성한 결과물을 똑같이 수행할 수 있다.

 

위 사진 속 터미널 화면을 보면 새롭게 생성한 webserver1-build 라는 이미지에서 build-python 이라는 컨테이너를 새롭게 생성한 후 해당 컨테이너에 들어가 python3 명령어를 치면 자동으로 python3 프로그램이 실행되는 것을 확인할 수 있다.

 

이제 좀 더 어려운 내용을 배워보자. 이번엔 Python3에 내장된 웹서버를 호스팅하는 것까지 한 번에 실행할 수 있도록 Dockerfile 파일 내용을 작성해보자.

 

 

위 명령어를 이어서 해석하자면 /var/www/http 라는 디렉토리를 만들어서 다음의 명령어를 실행하라는 의미이다.

 

python3 -u -m http.server

 

자, 이제 위 Dockerfile을 아까처럼 build 명령어로 실행시켜보고 결과화면을 확인해보자. 참고로 아래의 두번째 줄 명령어는 혹시 생성할 새로운 컨테이너 이름으로 된 컨테이너가 이미 존재하면 기존의 컨테이너를 삭제하는 중복 체크용 명령어라고 할 수 있다.

 

docker build -t [생성할 새로운 이미지 이름] [Dockerfile 디렉토리 경로];
docker rm --force [생성할 새로운 컨테이너 이름];
docker run --name [생성할 새로운 컨테이너 이름] -it [생성할 새로운 이미지 이름]

 

결과화면

 

위 결과 화면을 보면 자동으로 http://localhost:8000/ 에 웹서버가 호스팅된 것을 볼 수 있다. 그런데 해당 url로 들어가면 웹서버에 접근이 불가능하다. 왜 그럴까? 바로 호스트의 포트번호와 위에서 생성한 컨테이너의 포트번호를 연결시켜주지 않았기 때문이다. 따라서 컨테이너를 run 시킬 때 다음과 같은 명령어를 추가해서 다시 실행시켜보자. 참고로 포트번호를 연결해주는 것에 대해서는 저번 포스팅에서 배웠던 적이 있다.

 

docker build -t [생성할 새로운 이미지 이름] [Dockerfile 디렉토리 경로];
docker rm --force [생성할 새로운 컨테이너 이름];
docker run --name [생성할 새로운 컨테이너 이름] -p [호스트 포트번호]:8000 -it [생성할 새로운 이미지 이름]

 

참고로 Python3 웹서버 포트번호는 8000번 고정이기 때문에 수정을 해서는 안 된다. 위 명령어를 입력하고 필자는 필자의 컴퓨터의 8080 포트번호로 연결해놓았기 때문에 http://localhost:8080 으로 들어가면 아래와 같이 index.html 내용이 출력되는 것을 볼 수 있다.

 


추가적으로 Dockerfile 파일에 작성하는 명령어들에 대해 좀 더 알아보자. CMD와 RUN 명령어의 차이점은 RUN 명령어는 생성할 이미지에 적용되는 반면 CMD는 생성된 이미지에서 새롭게 생성할 컨테이너에서 실행될 명령어라는 것으로 구분할 수 있다. 참고로 위처럼 CMD로 Python3 웹서버를 호스팅하는 방법 대신에 RUN 명령어를 추가로 또 작성해주는 방법도 있다. 아래와 같이 말이다.

 

RUN 명렁어를 추가해서 웹서버 호스팅하기

 

또 다른 방법으로는 호스트 파일 시스템 즉, 로컬 파일 시스템에 index.html 이라는 파일을 만들어주고 이 파일을 복사한 후 생성할 컨테이너에 붙여넣기 하여 웹서버를 호스팅할 수 있다. 아래와 같이 말이다.

 

 

COPY 명령어에 대한 해석은 로컬 파일 시스템에 있는 index.html 을 컨테이너 내부의 현재 디렉토리(.) 즉, 위 예시에서는 컨테이너 내부의 /var/www/http 디렉토리에다가 복사를 해라 라는 의미이다. 그리고 build 명령어는 동일하게 작성하여 웹 서버를 호스팅할 수 있다.


끝으로, 인카토스라는 회사에서 감사하게도 제게 협찬을 해주신 제품을 하나 소개하려고 합니다. 그것은 바로 아래 사진의 Docker 컨테이너 각티슈 케이스입니다!

 

인카토스에서 협찬해주신 Docker 컨테이너 각티슈 휴지 케이스

 

개발 공부를 하다 보면 원인불명의 에러 때문에 땀을 흘리거나 눈물(?)을 흘리기도 하는데요! 겨울철엔  감기라도 걸리면 모니터 앞에서 콧물을 흘리기도, 한여름엔 개발을 너무 열심히 한 나머지 땀을 흘리기도 합니다.

 

하지만 이 제품을 곁에 두고 개발을 하게 되면 귀여운 Docker 컨테이너가 제공하는 티슈 한 장을 편하게 뽑아 쓰면서 개발 텐션을 끊지 않고 이어갈 수 있답니다~!  특히, 마치 개발 관련 장비를 하나 늘린 것처럼 마음이 한켠 든든해지는 기분입니다! 해당 제품에 관심이 있으시다면 아래 링크로 들어가시면 됩니다. 다시 한 번 좋은 제품을 협찬해주신 인카토스에 감사인사 드립니다! :)

 

💡 판매처 인카토스 : https://incatos.shop/

반응형