지난 번에 도커에 대하여 간단하게 설명하면서,
도커는 이미지와 컨테이너를 통해서 동작한다고 이야기했는데, 오늘은 이 동작이 구체적으로 어떻게 수행되는지 직접 도커를 사용하면서 알아보겠습니다.
지난번에 도커의 동작 과정을 설명하면서 사용하였던 그림입니다.
Dockerfile을 통해서 이미지를 만들고, 이미지를 통하여 컨테이너를 만든다.
간단하게 축약하면 이렇게 설명할 수 있지만, 솔직히 처음 보는 입장에서는 Dockerfile이라는게 어떤 것이고, 이미지와 컨테이너도 아직 어떤 역할을 수행하는지 몰라서 어떻게 도커가 개발 환경을 구성해주는지 이해하지 못합니다.
따라서, 단계별로 설명하는 시간을 가져보도록 하겠습니다.
아니 단계별로 설명한다면서 왜 이미지부터 설명하냐고 생각하시는 분들이 있을 것 같은데, 개인적으로 이미지랑 컨테이너부터 설명한 뒤에 Dockerfile에 대해 설명하는 것이 더 낫다고 생각해서 순서를 이렇게 정했습니다.
[Reference : https://docs.docker.com/get-started/overview/]
일단 도커 공식 홈페이지에서 설명하고있는 이미지의 정의는 다음과 같습니다.
간단하게 번역하자면 이미지는 컨테이너를 만들기 위한 간단한 설명서이며, 이미지는 다른 사람이 생성한 이미지를 바탕으로 새롭게 생성하거나, 본인이 직접 이미지를 생성할 수 있습니다.
이미지를 생성하기 위해서는 Dockerfile을 build하여 이미지를 생성할 수 있으며, 만약 Dockerfile이 변경될 경우에는 이를 rebuild하여 이미지를 새로 생성해야합니다.
여기서 중요한 구문은 '컨테이너를 만들기 위한 설명서' 라는 구문 같다고 생각해요.
말 그대로 이미지를 통해서 컨테이너를 생성할 수 있는데, 이미지를 통하여 생성된 컨테이너는 우리가 원하는 프로그램이 설치된 컴퓨터와 같다고 생각하면 좋을 것 같습니다.
다른 사람들이 생성한 이미지를 저장하는 docker hub를 예시로 설명해보겠습니다.
docker hub에 접속하여 다음처럼 nginx에 대해서 검색을 수행할 경우, 다음처럼 nginx와 관련된 이미지들이 조회되는 것을 확인할 수 있습니다.
Docker official image라는 문구가 붙은 이미지의 경우, nginx에서 직접 docker hub에 저장한 이미지라는 것을 확인할 수 있습니다.
가장 상단에 위치한 이미지에 들어갈 경우,
다음처럼 우측 상단에 명령어와 함께 이미지에 대한 설명이 나와있는 것을 확인할 수 있습니다.
우측 상단에 위치한 명령어를 우리 환경에서 실행할 경우, nginx 이미지가 다운받아지는데, 우리는 이 이미지를 통하여 컨테이너를 실행할 수 있고, 컨테이너가 실행될 경우, 마치 우리 컴퓨터에 nginx가 설치된 것처럼 프로그램을 동작시킬 수 있습니다.
즉, 이미지는 컨테이너에서 실행하길 원하는 프로그램들의 설정들이 저장된 파일이라고 생각해도 좋을 것 같습니다.
그럼 뭐 대충 실행해보도록 하겠습니다.
일단 아무것도 설치되지 않은 환경에서 localhost:8080으로 접속할 경우, 다음처럼 화면이 출력되지 않는 것을 확인할 수 있을텐데, 이건 당연한 소리입니다.
그럼 도커를 통해 nginx 이미지를 다운받고, 이를 실행하여 localhost:8080에 출력 문구를 띄워보도록 하겠습니다.
일단 Docker Desktop이 실행되어있다는 가정하에 진행해보도록 하겠습니다.
터미널에 다음 명령어를 실행해줍니다.
그럼 다음처럼 docker hub로부터 이미지를 가져옵니다.
가져온 이미지는 다음의 명령어를 통하여 확인할 수 있습니다.
그럼 이 이미지를 통하여 컨테이너를 실행해보도록 하겠습니다.
기본적으로 docker run {이미지 이름}을 통하여 동작하며, 추가적인 태그들은 나중에 설명하는 시간을 갖도록 하겠습니다.
docker ps를 통하여 현재 실행 중인 컨테이너를 확인할 수 있으며, 정상적으로 컨테이너가 동작함을 확인했기 때문에 localhost:8080으로 접속하면,
다음처럼 nginx의 index 페이지를 확인할 수 있습니다.
사용자가 직접 이미지를 생성하여 커스텀 이미지를 생성할 수도 있는데, 이러한 작업은 Dockerfile을 통해서 이루어지기 때문에 이는 Dockerfile을 설명하면서 보여드릴 것 같습니다.
이미지를 직접 생성하느냐, docker hub에서 받아오느냐의 차이지, 실행하는 과정을 동일하기 때문에 설명을 생략하도록 하겠습니다.
다음으로는 컨테이너에 대한 설명을 이어갈텐데, 이미지를 설명하면서 컨테이너도 설명하는 바람에 내용은 많이 없을 것 같네요.
[Reference : https://docs.docker.com/get-started/overview/]
다음은 도커 공식 홈페이지에 명시되어있는 컨테이너의 정의입니다.
간단하게 번역해보자면, 컨테이너는 이미지를 통해서 만들어지는 일종의 객체이며, 생성된 컨테이너는 컨테이너끼리 서로 영향을 주지 않는 독립적인 상태를 띄고 있습니다. 따라서 사용자는 컨테이너를 생성하거나 실행하는 과정에서 여러 설정들을 수행할 수 있고, 이에 따라서 컨테이너가 어떻게 동작할지를 설정할 수 있습니다.
기본적으로 컨테이너는 종료 될 경우 컨테이너가 실행되면서 수행하였던 모든 설정들이 초기화됩니다.
여기서 설명하는 실행하는 과정에서 수행하는 설정들은 아까 docker run 과정에서 사용하였던 여러 태그들을 의미하는데, 이 태그들을 통하여 포트 포워딩, 실행 모드, 볼륭 등의 설정들을 수행할 수 있습니다.
이 부분은 나중에 설명하는 시간을 갖도록 하겠습니다.
네 마지막으로 이제 Dockerfile에 대해서 설명하는 시간입니다.
우리가 필요한 이미지를 docker hub로부터 다운할 수 있지만, 사실상 우리가 작업을 수행하면서 이미지 하나로만 수행할 수 있는 작업은 매우 드뭅니다.
예를 들어서, 제 경험을 토대로 설명해보면 저는 nodeJS를 다운받아, 해당 프로그램에서 활용할 수 있는 명령어인 npm start라던가 이러한 명령어를 사용하여 프론트엔드 프로젝트를 실행해야했습니다.
만약 아까와 같은 방식으로 node 이미지를 다운받는다 할지라도, 추가적으로 명령어를 실행해야하기 때문에 우리는 node 이미지를 기반으로 작업을 수행하는 특별한 이미지를 생성해야합니다.
이러한 경우에 Dockerfile을 통하여 이미지를 생성합니다.
Dockerfile의 경우, 다음처럼 파일의 이름을 Dockerfile이라고 지정하면 끝입니다.
이 경우 도커가 Dockerfile을 자동으로 인식하여 이미지로 변환해줍니다.
일단 도커 강의에서 사용했던 프론트 파일을 그대로 들고 왔습니다.
만약 서버가 실행된다면, localhost:3000에 접속할 경우 Hi there! 이라는 문구를 볼 수 있을겁니다.
그러나 제 노트북에는 node가 설치되어있지 않기 때문에 이 프로젝트를 실행할 수 없습니다.
이때 Dockerfile을 다음처럼 작성한 뒤,
docker build 명령어를 통하여 Dockerfile을 이미지로 변환해줍니다.
저는 별도의 설정을 통하여 이미지의 이름을 custom으로 설정해주었습니다.
그럼 다음처럼 custom 이라는 이름을 가진 이미지를 확인할 수 있으며,
이 custom 이미지를 docker run 명령어를 통하여 실행할 수 있습니다.
컨테이너가 실행중이니, localhost:3000으로 접속해보면,
다음처럼 로컬 환경에 node가 설치되지 않았음에도 불구하고 서버가 정상적으로 동작하는 것을 확인할 수 있었습니다.
일단 간단하게 Dockerfile 명령어를 설명하면 다음과 같습니다.
FROM node -> 배경이 되는 이미지 이름
WORKDIR /app -> 작업 위치 설정
COPY . . -> 로컬의 환경을 컨테이너 환경에 복사
RUN npm install -> 이미지를 바탕으로 실행할 명령어
COPY . . -> 로컬의 환경을 컨테이너 환경에 복사
EXPOSE 3000 -> 컨테이너 외부로 노출할 포트
CMD [ "node" , "app.mjs" ] -> 최종적으로 실행할 명령어
일단 정말 간단하게 Dockerfile, Image, Container의 동작 방식에 대해서 알아보았는데, 도커의 동작 방식에 중점을 맞췄기 때문에 명령어나 태그에 대한 설명을 생략해서 아직 모르는 부분이 많을거라 생각합니다.
그 부분에 대해서는 다음에 설명하는 시간을 갖도록 하겠습니다.