FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD ["node","server.js"]
FROM node
이미지의 이름을 넣어 준다.
COPY . /app
COPY . .
기본적으로 여기에서 두 개의 경로를 지정한다.
첫 번째 경로는 컨테이너의 외부,이미지의 외부 경로이며
이미로 복사되어야 할 파일들이 있는곳
첫 번째 '.' 은 도커에서 기본적으로 Dockerfile이 포함된 동일한 폴더임을 알리는것이다.
Dockerfile은 제외된다.
이 프로젝트의 모든 폴더,하위 폴더 및 파일을 복사해야 한다고 도커에 알리는것
두번째 '.'은 그 파일을 저장해야 하는 이미지 내부의 경로 이다.
(첫 번째 '.' : Host file system, 두 번째 '.' : Image/container file system)
모든 이미지와 이미지를 기반으로 생성된 모든 컨테이너에는 로컬 머신의 파일 시스템에서 완전히 분리된 자체
내부 파일 시스템이 있다.
도커 컨테이너 내부에 숨겨져 있는데
두 번째 '.' 부분에 루트폴더 즉 도커 컨테이너의 루트 엔트리를 사용하지 않고 사용자가 선택한 서브 폴더를 사용하는 것이 좋다.
원하는 대로 이름을 지정할 수 있다.
이제 Dockerfile과 동일한 폴더에 있는 모든 파일과 거기에 있는 모든 하위 폴더가 컨테이너 내부의 app 폴더에 복사된다.
이 폴더가 존재하지 않는 경우에는 이미지와 컨테이너에 생성된다.
노드 어플리케이션의 경우 노드 어플리케이션의 모든 종속성을 설치하기 위해 npm install 을 실행해야 한 다.
도커에도 이를 수행할 수 있는 명령어가 있다.
모든 로컬 파일을 이미지에 복사한 후 이미지에서 명령을 RUN 하고 싶다고 알릴 수 있다.
이 경우 npm install 이다.
COPY . ./
컨테이너 내부 파일 시스템 내에서 './' 이 경로는 /app을 나타낸다.
하지만 여기에서 위처럼 절대 경로인 /app이라고 설정할 수도 있다.
이렇게 하면 파일을 복사할 위치를 명확히 알 수 있고 현재 작업 디렉토리가 무엇인지 보기위해 파일을 추측하거나 살펴볼 필요가 없다.
RUN npm install
디폴트로 이러한 모든 명령은 도커 컨테이너 및 이미지의 작업 디렉토리에서 실행 된다.
디폴트로 그 작업 디렉토리는 컨테이너 파일 시스템의 루트 폴더이다.
COPY . /app 이부분에서 코드를 app 폴더에 복사하고 있기 때문에 npm install도 app 폴더 내에서 실
행하고 싶다.
도커에게 모든 명령이 그 폴더(app)에서 실행되어야 한다고 알려주는 편리한 방법은 모든 것을 복사하기 전에
WORKDIR를 설정하는 것이다. (COPY 명령 전에 적어준다.)
EXPOSE 80
이 노드 웸서버는 app.listen(80)(server.js안의 코드); 포트 80에서 수신 대기하게 된다.
도커 컨테이너는 우리의 지역 환경과 격리되어 있다.
결과적으로 자체 내부 네트워크도 있다.
컨테이너 내부의 노드 어플리케이션에서 포트 80을 수신할 때 컨테이너는 그 포트를 우리의 로컬 머신에 노출하진 않는다.
따라서 컨테이너 내부에서만 무언가를 수신 대기 중이기 때문에 그 포트에서 수신할 수 없는것이다.
언제나 Dockerfile의 마지막 명령 전에 이 컨테이너가 시작될때 우리의 로컬 시스템에 특정 포트를 노출하고 싶다는것을 도커에 알려야 하기 때문에 EXPOSE 명령을 추가해야 한다.
그런 후에 이 80포트를 수신하고 있는 컨테이너를 실행할 수 있게 되는것이다.
CMD ["node","server.js"]
마지막 명령은 모든 작업이 완료되면 서버를 시작하라는 것이다.
RUN node server.js라고 할 수 있지만 이건 틀린것이다.
이 이미지가 빌드될 때마다 실행되기 때문에 이 명령은 올바르지 않다.
위의 모든 명령은 이미지 설정을 위한 도커에 대한 명령이다.
이미지는 컨테이너의 템플릿이어야 함을 명심해야 한다.
이미지를 실행하는 것이 아니라 이미지를 기반으로 컨테이너를 실행하는 것이다.
RUN node server.js 이 명령을 사용하여 이미지와 템플릿에서 서버를 시작하려고 시도하지만
이미지를 기반으로 컨테이너를 시작하는 경우에만 서버를 시작하고 싶기 때문에 RUN node server.js 로 명령을 하지 않는다.
하나의 동일한 이미지에서 여러 컨테이너를 시작하면 노드 서버도 여러개 시작된다.
따라서 이를 위한 또 다른 명령이 있다.
CMD 명령이다.
RUN 과의 차이점은 이미지가 생성될 때 실행되지 않고 이미지를 기반으로 컨테이너가 시작 될때 실행 된다는 것이다.
컨테이너가 실행된 후에 노드 서버를 실행하고자 하는것이다.
CMD 에는 배열을 전달해야 한다.
도커에게 이미지를 기반으로 컨테이너가 생성될 때마다 그 컨테이너 내부에 있는 node 명령을 사용하여
server.js 파일을 실행하도록 지시한다.(CMD에 특정하지 않으면 베이스 이미지가 실행되며,그게 없는 경우 에러가 발생한다.)