개발 무지렁이

[Docker] 도커허브(DockerHub)에서 공식 베이스 이미지를 가져와 자체 이미지 구축(in Dockerfile) 본문

Backend/Docker

[Docker] 도커허브(DockerHub)에서 공식 베이스 이미지를 가져와 자체 이미지 구축(in Dockerfile)

Gaejirang-e 2023. 11. 4. 22:45

𐂂 도커허브(Docker Hub)
docker run [이미지NAME]
: 이미지실행 인스턴스(= 컨테이너)를 만든다.

도커허브에서 이미 존재하는 이미지 (🏅 Docker Official Image)를 사용할 수 있다.
즉, 해당 이미지가 내 로컬에 없으면, 도커허브에서 자동으로 이미지를 가져온다.
(이미지컨테이너에 필요한 모든 논리와 코드, 환경을 보관하고 있다.)

그렇게 가져와서 실제로 실행중인 이미지 인스턴스를 '컨테이너'라 부르는데,
컨테이너주변환경과 격리되어 있고, 격리*되어 실행된다.
⚠️ 컨테이너 내부에서 실행 중인 인터렉티브 쉘이 있다고 해서,
  이 쉘이 사용자에게 노출된다는 의미가 아니다.(격리되어 있기 때문에)
  (ex. 노드에 의해 노출된 인터렉티브 쉘컨테이너에 의해 자동으로 사용자에게 노출되지 않는다.)

인터렉티브 쉘(Interactive Shell)
: 사용자가 컴퓨터시스템명령을 입력하여,
실시간으로 결과를 확인할 수 있는 환경을 가리킨다.
(터미널 or 명령 프롬프트를 통해 Access 된다.)

docker run -it [이미지NAME](ex. node)
-i (interactive mode)
: 표준 입력을 열린상태로 유지하여, 입력을 수신하는 컨테이너 프로세스와 연결.
-t (psuedo mode)
: 의사 tty 할당: 터미널 생성

🎮 -it
: 이 두개를 결합하면, 컨테이너에 의해 노출되는 터미널을 통해
컨테이너 입력을 수신할 수 있다.
( 도커에게 컨테이너 내부에서 호스팅머신으로 대화형 세션을 노출 명령)
( 해당 이미지컨테이너 내부에서 실행된다, 로컬 시스템에 노드를 설치할 필요가 없다.)

𐁍 공식 베이스 이미지 위에 코드를 추가하여 Custom 이미지를 구축할 수 있다.
🐋 Dockerfile
: 도커에 의해 식별되는 특별한 이름으로써
자체 이미지에 대한 설정 명령을 할 수 있다.

🦐 FROM [DockerHub상 이미지 NAME]
: 도커허브로부터 이미지로컬로 다운로드 및 캐시된다. (로컬 도커허브 이미지)

🦐 WORKDIR [작업디렉터리 NAME]
: 도커 컨테이너작업디렉터리 설정.
후속 명령이 폴더 내부에서 실행된다.**

🦐 COPY [컨테이너 외부 이미지 경로] [이미지 내부 경로]
[컨테이너 외부 이미지 경로]: 이미지복사되어야할 파일들이 있는 곳
              기본적으로 Dockerfile이 포함된 동일한 폴더를 말한다.
              (복사될 때 Dockerfile제외된다.)

[이미지 내부 경로]: 모든 이미지컨테이너에는 로컬머신의 파일시스템에서 완전히 분리된
          자체 내부 파일시스템이 있다.(도커 컨테이너 내부에 숨겨져 있다.)
          사용자가 생성한 서브폴더를 사용하는 것이 좋다. (COPY . /app)

: 도커에게 로컬머신에 있는 파일도커 이미지
내부 파일시스템어떤 경로에 들어가야 하는지를 알려준다.

🦐 RUN npm install
: 애플리케이션에 필요한 모든 종속성 설치
(도커 이미지컨테이너작업 디렉터리에서 실행.)
(Default: 작업디렉터리컨테이너 파일시스템루트 폴더이다.)

🦐 EXPOSE 80
: 컨테이너가 시작될 때 로컬머신특정 포트를 노출시키겠다고 도커에 알림.
(도커 컨테이너격리되어 있다. 즉, 컨테이너 내부에서만 수신대기하는 것은 의미가 없다.)
(즉, 수신대기하고 있는 port를 밖으로 노출해야 한다.)

⚠️ 이 명령은 documentation 목적으로만 추가한다.(즉, 선택사항이지만 권고.)

🦐 RUN node server.js(x) | CMD ["node", "server.js"] (o)
: 모든 작업이 완료되면 서버 js파일을 실행해야함을 알림.

전자는,
이미지가 빌드될 때마다 실행하는 명령임으로 올바르지 않은 명령이다.

후자는,
이미지를 실행하는 것이 아니라,
이미지를 기반으로 컨테이너를 실행하는 것이다
(⚠️ 이미지컨테이너템플릿이어야 한다.)

CMD
이미지가 생성될 때, 실행되지 않고,
이미지를 기반으로 컨테이너가 시작될때 실행된다.

🍩 배열을 전달 (명령을 두개의 문자열로 분할)
이미지를 기반으로 컨테이너가 생성될 때마다
컨테이너 내부에 있는 node 명령을 사용하여 server.js 파일을 실행하도록 지시
(⚠️ CMD에 배열로 특정하지 않으면 베이스 이미지실행되고, 이게 없다면 에러 발생)

🦉 docker build .: Dockerfile에 작성한 명령에 따라 이미지생성
.:명령을 실행하는 곳과 동일한 폴더에, Dockerfile이 존재함을 도커에게 알림.

𖠃 docker run [Custom 이미지ID]: ERR_CONNECTION_REFUSED
해당 이미지를 기반으로 컨테이너를 실행
(컨테이너명령을 모두 완료할 때까지 종료되지 않는다, 서버를 켜논 상태를 유지)
(⚠️ 하지만, localhost:80을 브라우저에 쳐보면 연결되어 있지 않다는 에러 발생, ERR_CONNECTINO_REFUSED)

WHY 작동하지 않을까?
Dockerfile에 작성된 EXPOSE 80은 정말 documentation 목적의 명령이다
즉, 이미지 기반으로 컨테이너를 실행할 때, 옵션으로써 도커에게
로컬머신어떤 포트(port)도커 컨테이너 내부어떤 포트(port)Access할 수 있는지를 알려줘야 한다.

docker run -p [로컬머신에서 Access하려는 로컬포트]:[도커 컨테이너 내부의 노출 포트] [Custom 이미지ID]
(ex. docker run -p 3000:80 [Custom 이미지ID])

로컬포트(port) 3000publish(-p)되었기 때문에 정상 동작한다

🦉 docker stop [컨테이너NAME]
: 도커를 수동으로 정지.
Comments