dockerHub나 다양한 커뮤니티에서 이미지를 공유하고 있지만, 당연하게도 자체 애플리케이션에 최적화 된 이미지가 필요하다. 이를 위해서 dockerfile을 작성하고 이미지를 직접 빌드할 수 있어야 한다. 이미지를 빌드하는 방법은 아래와 같다.
Dockerfile을 만든다. VScode의 경우에는 Docker 익스텐션을 이용하여, Docker 명령을 이용하여 도커파일을 작성하는 데 도움을 준다. → 필수는 아니다. dockerfile을 만드는 것은 VScode뿐 아니라 다른 에디터에서도 당연히 도움을 받을 수 있다.
FROM 명령어를 통해 다른 베이스 이미지에서 자체적인 이미지 구축이 가능해진다. 이론적으로는 도커 이미지를 처음부터 빌드할 수 있지만, 운영 체제 레이어가 필요하다. → 어떤 이미지의 이름을 넣는 데, 내 시스템에 있거나 DockerHub에 있는 이미지의 이름을 넣으면 된다.
COPY 명령어를 통해 도커에게 로컬 머신에 있는 파일이 이미지에 들어가야 하는 지 알릴 수 있다. COPY . . → 첫 번째 경로는 컨테이너의 외부, 이미지의 경로이며 이미지로 복사되어야 할 파일들이 있는 곳이다. . 이 의미하는 바는 도커 파일이 포함된 동일한 폴더임을 알리는 것이다. Dockerfile은 당연히 제외된다. 두 번째 경로는 그 파일을 저장해야 하는 이미지 내부의 경로이다.
모든 이미지와 이미지를 기반으로 하는 컨테이너는 로컬 머신의 파일 시스템에서 완전히 분리된 자체 내부 파일 시스템을 가지고 있다. 사용자가 선택한 서브 폴더를 사용하는 것이 좋다. 폴더가 존재하지 않는 경우는 이미지와 컨테이너에 생성된다.
WORKDIR 명령을 통해 도커 후속 명령이 어디로 내리는 지 정해줄 수 있다. RUN뿐만 아니라 COPY도 이 디렉토리를 기준으로 실행한다.
6.RUN 명령을 통해 이미지에서 명령이 가능하다. npm install → 종속성 설치
FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
#RUN node server.js
CMD ["node","server.js"]
해당 docker file은 아주 간단한 예제이다. docker 공식문서를 확인하면 dockerfile에 사용할 수 있는 다양한 명령어들을 확인할 수 있다.
기본적으로 작성했던 DockerFile을 이미지로, 그 이미지를 궁극적으로는 컨테이너로 변환한다.
docker build .
→ 도커 파일을 기반으로 새 커스텀 이미지를 빌드하도록 도커에게 지시하는 명령어, 동일 디렉토리에 있기 때문에 위치를 알린다.
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 138B 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:latest 1.8s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 295B 0.0s
=> CACHED [1/4] FROM docker.io/library/node@sha256:5881d9cbba5b4bf1c52f9a448d949257644dba1c8b36f81c56a520468353b38c 0.0s
=> [2/4] WORKDIR /app 0.1s
=> [3/4] COPY . /app 0.1s
=> [4/4] RUN npm install 4.1s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:c53d00cd9ef9ff9fcd6cbb1e7317a7f6bc2ecc79d89423d3a49fe6cf009d4e80
빌드를 진행하면 나오는 진행사항이다. 마지막을 통해 이미지의 id를 알 수 있다.
docker run c53d00cd9ef9ff9fcd6cbb1e7317a7f6bc2ecc79d89423d3a49fe6cf009d4e80
이후 완성된 이미지를 가지고 컨테이너 실행을 한다. 이미지에 CMD 명령어로 노드 서버를 실행하기 때문에 종료되지 않고 진행 중인 프로세스로 남는다. ( 포그라운드 )
도커 데스크탑 애플리케이션을 확인하면 더 정확히 확인 할 수 있다.
docker stop awesome_mendeleev 명령으로 이 컨테이너와 컨테이너 내부에서 실행 중인 노드 서버를 종료할 수 있다. 당연히 도커 데스크탑 애플리케이션에서도 종료가 가능하다.
PS C:dockerStudy\nodejs-app-starting-setup> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
80587a671c2d c53d00cd9ef9 "docker-entrypoint.s…" 4 minutes ago Exited (137) 28 seconds ago awesome_mendeleev
docker run -p c53d00cd9ef9ff9fcd6cbb1e7317a7f6bc2ecc79d89423d3a49fe6cf009d4e80 명령을 통해 도커에게 어떤 로컬 포트가 있는 지 알릴 수 있다. ( -p 플래그 ) docker run -p 4000:80 c53d00cd9ef9ff9fcd6cbb1e7317a7f6bc2ecc79d89423d3a49fe6cf009d4e80 플래그 뒤에 외부포트:내부포트를 지정하여 서버에 접속할 수 있게 한다.
터미널에서 명령어를 통해 제어, 실행도 가능하지만 도커 데스크탑을 통해 GUI로 간단하게 제어도 가능하다. 명령어를 통해 세부적인 옵션 같은 것들을 편하게 줄 수 있어서 GUI가 당연히 더 좋다 이런 것은 아니다.
아주 간단한 예제와 실행을 통해 이미지를 빌드하고, 컨테이너를 실행해 보았다. 실제 애플리케이션 코드를 포함하면 더 다양한 명령와 옵션이 필요할 것이다. 오늘은 실습 위주로 간단하게 알아보고 다음에는 이미지와 컨테이너, 레이어들에 대해서 조금 더 깊게 알아보도록 하자.