Docker 실행..
docker run node
- 노드를 기반으로 컨테이너를 실행한다.
- 하지만, 노드에 의해 노출된 인터렉티브 쉘은 우리에게 자동으로 노출되지 않기 때문에 이 명령어를 사용해도 컨테이너만 생성될 뿐 아무 변화도 없다.
docker run -it node
- 도커 컨테이너 내부에서 호스팅 머신으로 대화형 세션을 노출하고 싶다고 알린다.
- 그러면 기본 노드 명령을 실행할 수 있는 인터렉티브 노드 터미널로 접속이 가능하다!
→ 우리 컴퓨터 안에서 노드가 설치되진 않았지만 노드가 실제로 컨테이너 안에서 실행중이며, 노드와 상호작용 할 수 있다는 걸 알 수 있다.
터미널로 나와보면,…
- 도커 컨테이너 내의 노드 버전과 내 컴퓨터에 있는 노드 버전이 다른 걸 알 수 있다.
- 나는 아까 컨테이너 안의 노드와 상호작용 했다는 뜻!
→ 이렇게 하면 시스템에 노드를 설치할 필요가 없다!
Dockerfile
자체 이미지를 빌드할 때 실행하려는 도커 명령 → 설정 명령이 포함되어 있다.
FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD ["node", "server.js"]
FROM node
- 실행에 필요한 운영체제 레이어, 도커 허브 상의 이미지 이름으로 넣는다.
WORKDIR /app
- 모든 후속 명령이 해당 디렉토리에서 실행한다.
COPY . /app
- 로컬 머신에 있는 파일이 이미지에 들어가야하는지 알린다.
- 프로젝트 루트 디렉토리의 모든 폴더가 → 컨테이너 내부의 /app 에 복사된다.
- 첫번째 . : 컨테이너 외부(이미지 외부 경로) 이미지로 복사되어야 할 파일이 있는 곳.
- 도커 파일이 있는 경로라고 알려준다. 이 때, 도커 파일은 제외된다.
- 이 프로젝트의 모든 폴더, 하위 폴더를 이미지화 한다고 알린다.
- 두번째 /app : 이미지 저장 경로.
- . 이라고 하면 도커 컨테이너의 루트 엔트리
- 사용자가 선택한 서브 폴더를 사용하는 것이 좋다. (이름 지정 가능) → 존재하지 않으면 자동으로 만들어짐
- ./ 라고 쓰면 도커 컨테이너의 현재 작업 디렉토리, 즉 /app 에 복사된다.
- 하지만 보통 현재 작업 디렉토리를 명확하게 하기 위해 /app 으로 명시적으로 설정하는 게 좋다.
- . 이라고 하면 도커 컨테이너의 루트 엔트리
RUN npm install
- 해당 명령은 /app 디렉토리 안에서 실행된다. → WORKDIR 지정해줘야 함.
EXPOSE 80
- 도커 마지막 명령 전, 어떤 포트에 연결되어야 하는지 로컬 머신에게 지시한다.
CMD ["node", "server.js"]
- server.js 파일을 실행하도록 지시한다.
- 이미지를 실행시킬 때 실행되는 명령어가 아니라, 이미지를 기반으로 컨테이너가 시작될 때 실행되는 명령어.
- 띄어쓰기를 기준으로 배열로 줘야 함.
- CMD 에 명령어를 특정하지 않으면 베이스 이미지가 실행되고, 에러 발생.
💡 이미지는 컨테이너의 템플릿 임을 명심하자.
”이미지를 실행”시키는 것이 아니라, 이미지를 기반으로 “컨테이너를 실행”시키는 것!
이미지 빌드
docker build .
- Dockerfile 로 도커 이미지를 빌드하는 명령어
- . → 이 명령을 실행하는 곳과 동일한 곳에 Dockerfile 이 존재한다.
- . 앞에 이미지 이름을 써서 지정할 수 있다.
- docker build node_server:v1.0.0 .
- 이미지 이름 : node_server
- 태그 : v1.0.0
- docker build node_server:v1.0.0 .
실행하면
[+] Building 2.1s (9/9) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 2.06kB 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:latest 0.0s
=> [1/4] FROM docker.io/library/node 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 10.43kB 0.0s
=> [2/4] WORKDIR /app 0.0s
=> [3/4] COPY . /app 0.0s
=> [4/4] RUN npm install 1.9s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:4d1f959dcb74b20608582aeb4e4d9313e0f0e7c45ecca18f95ae5ca718cf2bd9
→ 내가 쓴 Dockerfile 이 실행된다.
- 제일 아랫줄이 이미지 id
docker run 4d1f959dcb74b20608582aeb4e4d9313e0f0e7c45ecca18f95ae5ca718cf2bd9
- 이걸 실행하면 도커 컨테이너가 멈추지 않고 실행된다.
- 컨테이너가 시작될 때 실행된 명령어 CMD ["node", "server.js"] 가 완료되지 않았기 때문 !
- 하지만 로컬에서 작동되지 않는다. 왜일까?
일단 컨테이너를 종료하자
# 내 로컬에 만들어져있는 모든 컨테이너 목록 보기
docker ps -a
# 컨테이너 목록
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bd1de1d2926b 4d1f959dcb74 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 80/tcp distracted_jennings
# 자동으로 만들어진 컨테이너 이름을 넣어서 정지시킨다. (container id 를 넣어도 됨)
docker stop distracted_jennings
# 컨테이너 삭제
docker rm distracted_jennings
왜 안될까요?
- 보면 요 노드 서버는 80 포트에서 요청을 받는다.
- 우리가 도커파일에서 EXPOSE 80 라고 80 포트를 사용한다고 해놓긴 했지만, 사실 이건 documentation 용…ㅎㅎ → 그래도 추가는 해줍시다!
- 80 포트를 사용하도록 설정해주쟈 ㅎ_ㅎ
# -p : publish
# 어떤 로컬 포트에 액세스 해야 하는지 알려준다.
# 로컬포트:내부 도커 컨테이너 노출 포트 (여기서는 80)
docker run -p 3000:80 4d1f959dcb74
이렇게 컨테이너를 실행시키고 http://localhost:3000 에 접속하쟈
성고옹~ 🫡
💡 결국 EXPOSE 80 은 선택 사항이고 이 포트를 사용할 것임을 문서화하는 작업이다. 실제로 도커 컨테이너를 빌드할 때 -p 를 사용해야만 실제 포트가 노출된다. 그래도 문서화하는 것이 모범적인 사용법이라고 한다.
💡 아이디를 사용하는 모든 docker 명령은 항상 전체 id 를 복사 / 붙여넣기 할 필요는 없다!
첫 번째로 시작하는 문자 몇 개를 써도 충분하다.
만약, image id 가 a 로 시작하는 컨테이너가 단 한 개 라면? → docker run a 명령어로 해당 컨테이너를 실행 가능하다!
728x90
'개발공부 개발새발 > Docker' 카테고리의 다른 글
Docker ) Network (0) | 2024.03.29 |
---|---|
Docker ) ARG 와 ENV (0) | 2024.03.18 |
Docker ) 도커 볼륨과 바인드 마운트 (0) | 2024.03.18 |
Docker ) 이미지, 컨테이너 관리. (0) | 2024.03.03 |
Docker ) 도커 이미지 기초 (1) | 2024.02.28 |