도커는 컨테이너 기반의 오픈소스 가상화 플랫폼입니다.
컨테이너라 하면 배에 실는 네모난 화물 수송용 박스를 생각할 수 있는데 각각의 컨테이너 안에는 옷, 신발, 전자제품, 술, 과일등 다양한 화물을 넣을 수 있고 규격화되어 컨테이너선이나 트레일러등 다양한 운송수단으로 쉽게 옮길 수 있습니다.
서버에서 이야기하는 컨테이너도 이와 비슷한데 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해줍니다. 백엔드 프로그램, 데이터베이스 서버, 메시지 큐등 어떤 프로그램도 컨테이너로 추상화할 수 있고 조립PC, AWS, Azure, Google cloud등 어디에서든 실행할 수 있습니다.
Docker는 부팅등 운영체제의 핵심 기능(커널)은 공유하기 때문에 기존에 쓰이던 VM보다 가볍습니다.
Docker를 사용함으로써 모든 개발자의 개발환경을 쉽게 통일하여 충돌 문제가 없고,
환경이 다 이미지로 셋팅되어있기에 배포 또는 새컴퓨터에서 작업을 시작할 때 편하다는 장점이 있습니다.
또한 한 컴퓨터에서 다른 환경의 여러 서비스를 실행해야 하는 경우, 컨테이너로 분리되어 있기 때문에 서로 독립되어 실행할 수 있습니다.
컨테이너를 실행하기 전에 먼저 해줘야할 것은 이미지를 만드는 것입니다. Dockerfile 이라는 이름의 파일을 만들고 이미지를 만들기 위한 명령어를 입력합니다. 그리고 docker build 명령어를 통해 이미지를 만들게 됩니다.
FROM node:16
WORKDIR /my_backend/
COPY . /my_backend/
CMD node index.js
FROM 리눅스:최신버전
이런식으로 쓰면, 리눅스의 최신 버전이 깔린 컴퓨터가 한대 만들어집니다.
그런데 우리는 컴퓨터에 node, npm, yarn도 깔아야 합니다.
도커에는 다른 사람들이 만들어놓은 여러 이미지가 있는데(Docker hub) 우리가 필요한 것들이 이미 깔려있는 이미지도 있습니다.
FROM node:16
을 하면 node, npm, yarn이 모두 깔린 리눅스 컴퓨터가 하나 생기게 됩니다.
윈도우에서는 WSL2의 설치를 해주어야 리눅스 환경을 사용할 수 있습니다.
COPY . /my_backend/
는 밖에 있는 소스 코드를 모두 my_backend 폴더로 복붙하겠다는 뜻입니다.
CMD node index.js
를 통해서 복사해서 넣은 파일을 실행해줍니다.
그런데 어디서 저 명령어를 실행할지를 모르기 때문에, 시작할 작업 폴더를 지정(생성)해줍니다.WORKDIR /my_backend/
docker build . : 이미지 패키징
docker images : 이미지보기
docker run 이미지아이디 : 컴퓨터실행
docker ps : 도커 프로세스(도커 컨테이너 목록)
docker ps -a : 전체보여주기(꺼진 컨테이너(컴퓨터)포함)
docker rm 컨테이너아이디 : 컨테이너 제거
docker rmi 이미지아이디 : 이미지 제거
docker stop 컨테이너아이디 : 실행 종료
docker exec -it 컨테이너아이디 /bin/bash : 도커 내부(가상 컴퓨터 터미널)로 이동(bash쉘 적용) / top : 실행중 프로세스 목록보기(리눅스/맥)
Docker를 사용하는 이유는 모든 환경을 통일하기 위함이기에
node_modules같은 설치폴더는 폴더를 복제하는게 아닌 도커내에서 설치하여 버전을 같게합니다.
FROM node:16
WORKDIR /my_backend/
COPY . /my_backend/
RUN yarn install
CMD yarn dev
따라서 yarn install을 Docker에서 RUN(실행 및 포장)해주고
로컬에 설치된 node_modules는 복제되지 않도록 .dockerignore 파일에 추가해줍니다.
CMD는 포장 후에 포장된 이미지를 실행하는 명령이기에 한번만 쓸 수 있습니다.
RUN yarn dev로 같이 포장하면 포장이 끝나지 않습니다.(익스프레스 리슨)
docker에서 실행한 서버는 포트포워딩 해줘야합니다. (로컬로 온 요청을 도커로 포워딩)
docker는 Dockerfile
을 보면서 빌드할 때 처음부터 한번에 다 패키징하는게 아니라
한줄씩 이미지 패키징되면서 바뀐게 없으면 기존의 것을 그대로 쓰고 아니면 거기부턴 아래까지 새로 굽습니다.
FROM node:16
WORKDIR /myfolder/
COPY ./package.json /myfolder/
COPY ./yarn.lock /myfolder/
RUN yarn install
COPY . /myfolder/
CMD yarn dev
따라서 재설치시 부담이되는 yarn install의 실행이 package.json의 변경사항이없다면 실행되지않도록 전체 파일들을 패키징하는 것보다 위로 올려서 패키징했습니다. 이렇게 분리하면 다시 빌드될때 package.json과 yarn.lock파일로 먼저 node_modules를 설치해줄때 변경 사항이 없으면 install하지않고 기존의 저장되어있던 것을 그대로 씁니다.
yarn.lock파일은 package.json 파일과 셋트로 같이 움직여야 합니다.(의존하고있는 라이브러리들의 버전이 다를 수 있음)