1. Docker
도커가 없다면 NodeJS환경에서 프로젝트 진행시 npm install로 모듈들을 설치해줘야 한다.
하지만 도커가 있다면 이들을 설치하지 않고 사용할 수 있다.
2. Dockerfile
Dockerfile이란 파일명을 도커가 식별한다.
Dockerfile에는 자체 이미지를 빌드할때 실행하려는 도커에 대한 명령이 포함된다.
Dockerfile 예시
FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD ["node", "server.js"]
FROM
일반적으로 FROM 명령어로 시작한다.
이를 통해 다른 베이스 이미지에 나만의 이미지를 구축할 수 있다.
node라는 이미지로부터 시작한다는 뜻이다.
이미 나만의 시스템에 존재하거나 도커 허브상의 이미지 이름을 넣는다.
실제로 이 도커 허브 이미지를 기반으로 컨테이너를 처음 실행했을때
이 이미지가 로컬로 다운로드 및 캐시되었기 때문에 실제로 이 이미지를 기반으로
컨테이너를 실행한 순간 로컬머신에도 존재하게 된다.
COPY
도커에게 로컬머신에 있는 어떤 파일이 이미지에 들어가야 하는지 알려준다.
COPY (복사할것) (저장하는이미지경로)
. 을 넣으면 도커에게 기본적으로 Dockerfile이 포함된 동일한 폴더임을 알리는 것이다.
첫번째 . 은 이 프로젝트의 모든 폴더, 하위폴더 및 파일을 복사해야한다고 도커에게 알리는 것이다.
두번째 매개변수 /app 은 이미지 내부에 app폴더에 첫번째 매개변수의 파일들을 저장한다.
모든 이미지와 이미지를 기반으로 생성된 모든 컨테이너는 로컬머신의 파일시스템에서
완전히 분리된 자체 내부 파일 시스템이 있다.
RUN
노드 애플리케이션의 모든 종속성을 설치하기 위해 npm install을 해야한다.
도커에도 모든 로컬 파일을 이미지에 복사한후 이미지에서 RUN하고 싶다고 알릴수 있다.
하지만 이 경우 디폴트로 이러한 모든 명령은 도커 컨테이너 및 이미지의 작업 디렉토리에서 실행된다.
디폴트로 그 작업 디렉토리는 컨테이너 파일 시스템의 루트 폴더이다.
WORKDIR
COPY를 통해서 app폴더로 파일들을 복사했기 때문에
npm install을 app폴더 내에서 실행하고 싶다고 알려야 한다.
WORKDIR는 도커 컨테이너의 작업 디렉토리를 설정하는 명령어이다.
이것은 도커에게 모든 후속 명령이 그 폴더 내부에서 실행될것임을 알리는 것이다.
WORKDIR로 루트 경로를 설정해줬으면 ./ 와 같이 상대경로로 COPY 명령어를 사용할수 있다.
CMD
RUN과 다른점은 이미지가 생성될때 실행되지 않고 이미지를 기반으로 컨테이너가 실행될때 실행된다.
EXPOSE
EXPOSE명령어는 선택적 사항이지만 포트를 나타내기 위해 써준다.
우리의 로컬환경과 도커 컨테이너는 격리되어 있다.
컨테이너 내부의 노드 애플리케이션에서 포트80을 수신할때
컨테이너는 그 포트를 우리의 로컬머신에 노출하지 않는다.
따라서 컨테이너 내부에서만 무언가를 수신 대기중이기 때문에 그 포트에서 수신할수 없는것이다.
3. 컨테이너 실행하기
새 커스텀 이미지 만들기
docker build .
. 은 도커에게 이 명령을 실행하는곳과 동일한 폴더에 Doockerfile이 존재함을 알린다.
생성된 이미지 아이디를 복사한 후
docker run 아이디
컨테이너가 실행된다.
만약 NodeJS환경에서 포트를 설정했다면 실행되지 않는다.
-p 플래그를 통해 우리의 로컬 머신의 어떤 포트가 이 내부의 도커 특정 포트에 엑세스 할수 있는지 알려줘야 한다.
나는 server.js라는 파일에 80번 포트로 listen하도록 코드를 구성했다.
해당 파일을 로컬호스트:3000에서 실행하고 싶다면 다음과 같이 명령어를 입력하면 된다.
docker run -p 3000:80 이미지아이디
4. 레이어
이미지는 읽기 전용이다.
build 후 코드를 바꾼다면 바로 적용되지 않는다. 적용하려면 다시 build를 해야 한다.
이미지는 잠겨있고 build되면 끝이다. 이미지의 모든것이 읽기 전용이기 때문이다.
과거에 해당 코드를 복사했기 때문에 단순히 코드를 업데이트 하여 외부에서 편집할수 없다.
이미지를 빌드하거나 이미지를 다시 빌드할때 변경된 부분의 명령과 그 이후의 모든 명령이 재평가 된다는 의미이다.
이미지를 빌드하고 아무것도 건드리지 않은 후 다시 빌드하면 처음 빌드할때보다 시간이 짧게 걸린다.
도커는 실제로 그 명령을 다시 거칠 필요가 없다고 추론한 것이다.
도커는 모든 명령 결과를 캐시하고 명령을 다시 실행할 필요가 없다면 이러한 캐시된 결과를 사용한다.
이것을 레이어 기반 아키텍처라고 한다.
최종명령 이전의 모든 명령은 이미 이미지의 일부이지만 별도의 레이어이다.
아무것도 변경되지 않으면 이러한 모든 레이어를 캐시에서 사용할 수 있다.
하지만 코드가 일부 변경되서 다시 빌드를 한다면 그 후의 다른 모든 명령도 실행된다.
위 Dockerfile을 보면 package.json이 변경되지 않아도 npm install을 다시 실행한다는 것이다.
도커는 다시 실행해야 하는 항목만 다시 빌드하여 다시 실행하기때문에 이미지 생성 속도를 높인다.
이 점을 활용하여 개선한다면 package.json을 먼저 복사한후 npm install 실행 후 다음 코드를 복사하면
코드만 변경 후 build시 package.json 파일안의 변경사항이 없기 때문에 npm install을 실행하지 않아 속도를 높일수 있다.
FROM node
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
EXPOSE 80
CMD ["node", "server.js"]
'개발 > Docker' 카테고리의 다른 글
[Docker] 도커 마운트 경로 오류 (0) | 2022.12.14 |
---|---|
[Docker] DockerHub 사용하기 (0) | 2022.12.13 |
[Docker] Docker 명령어 (0) | 2022.12.13 |
[Docker] 이미지와 컨테이너 (0) | 2022.12.13 |
[Docker] 도커의 개념 (0) | 2022.12.13 |