이 글은 [2024 NEW] 개발자를 위한 쉬운 도커 강의를 듣고 작성한 글입니다! 모든 강의자료 이미지 출처는 해당 강사님께 있습니다.
Node.js 로 개발된 소스코드를 애플리케이션으로 빌드하는 과정
Node.js가 설치되어 있는 OS 환경을 준비하고, Node.js 로 개발된 소스코드가 필요하다. 소스코드를 애플리케이션으로 빌드(여기에서의 빌드는 이미지의 빌드가 아니라 애플리케이션의 빌드이다.)해야 하고, 그 과정에서 애플리케이션을 실행할 때 필요한 라이브러리가 존재해야 한다. 소스코드가 있는 디렉토리에서 npm install을 하면 애플리케이션이 실행되기 위한 의존성 라이브러리가 설치된다. npm start 를 하면 애플리케이션을 실행한다.
애플리케이션 빌드
애플리케이션의 빌드란, 소스코드를 실행 가능한 상태로 만드는 것이다. 소스코드만 가지고 있는 상태로는 프로그램이라고 할 수 없다. 소스코드를 실행하기 위해 필요한 라이브러리를 설치하거나 소스코드를 실행 가능한 프로그램으로 만드는 과정이 필요하다. 이러한 과정을 통틀어 애플리케이션 빌드라고 한다. 애플리케이션 빌드를 통해 만들어진 결과물을 애플리케이션 프로그램 혹은 아티팩트라고 한다.
일반적인 소프트웨어를 실행할 때는 실행 환경을 준비하고, 프로그램만 준비하면 된다. 개발한 소스코드를 이미지로 빌드하려면 소스코드를 애플리케이션으로 빌드하고, 그 애플리케이션을 실행할 수 있는 환경을 준비하면 된다.
기본 Dockerfile 지시어
FROM 이미지명 : 베이스 이미지를 지정
COPY 빌드 컨텍스트 경로 레이어 경로 : 빌드 컨텍스트의 파일을 레이어에 복사, 새로운 레이어 추가됨
RUN 명령어 : 명령어를 실행, 새로운 레이어 추가됨
CMD ["명령어"] : 컨테이너 실행 시 명령어 지정, 컨테이너의 실행에만 사용되므로 별도의 이미지 레이어 추가하지 않음
WORKDIR 폴더명 : 작업 디렉토리를 지정 (리눅스나 윈도우의 cd 명령어와 유사)
USER 유저명 : 명령을 실행할 사용자 변경, 새로운 레이어가 추가됨
EXPOSE 포트번호 : 컨테이너가 사용할 포트를 명시
이미지 빌드 명령어
docker build -f Dockerfile 이름 -t 이미지명 Dockerfile 경로 : Dockerfile 명이 Dockerfile이 아닌 경우 별도 지정
환경변수 설정
ARG 변수명 변수값 : 이미지 빌드 시점의 환경 변수 설정, docker build --build-arg 변수명=변수값 으로 덮어쓰기 가능
ENV 변수명 변수값 : 이미지 빌드 및 컨테이너 실행 시점의 환경 변수 설정, 새로운 레이어가 추가됨, docker run -e 변수명=변수값 으로 덮어쓰기 가능
프로세스 실행
ENTRYPOINT ["명령어"] : 고정된 명령어를 지정
CMD ["명령어"] : 컨테이너 실행 시 실행 명령어 지정
레이어 추가에 대하여
파일시스템의 내용을 변경하는 부분이 있으면 일반적으로 레이어를 추가하고, 메타데이터만 추가하는 것은 레이어를 추가하지 않는다.
명령을 실행할 사용자 변경에 대하여
도커 컨테이너가 실행될 때 기본적으로 명령어들이 루트 사용자로 실행되기 때문에 실행된 프로세스가 굉장히 많은 권한을 가진다. 이 점은 보안에 취약할 수 있으므로 컨테이너가 불필요한 권한을 가지지 않도록 조절할 수 있다.
포트번호에 대하여
기본적으로 컨테이너가 모든 포트를 사용할 수 있는데, 굳이 EXPOSE 지시어를 사용하는 이유는 애플리케이션이 사용하는 포트를 문서처럼 기재하기 위해서이다. 이것을 보고 다른 사람은 프로젝트 소스코드를 보지 않아도 어떤 포트를 사용하는지 알 수 있다.
ARG와 ENV의 차이
컨테이너가 실행될 때 환경변수가 유지되는지에 대한 여부이다.
ENTRYPOINT와 CMD 지시어에 대하여
CMD에 들어가는 명령어는 띄어쓰기를 기준으로 여러 개를 작성할 수 있다. 일반적으로 고정되는 값이 있다.
node.js 환경에서는 npm start, npm install 과 같이, 중복되는 npm은 Dockerfile에서 ENTRYPOINT로 지정하여 관리할 수 있다.
ENTRYPOINT ["npm"]
CMD ["start"]
와 같이 작성했다면, ENTRYPOINT와 CMD가 합쳐져 실제 실행되는 명령어는 npm start 이다.
node.js를 기반으로 만들어진 envcolorapp을 통한 실습
실습1) 도커파일명이 Dockerfile-basic인 파일에 다음과 같이 작성한다.
FROM node:14
COPY ./ /
RUN npm install
CMD ["npm", "start"]
베이스 이미지는 node.js 14 버전이 설치되어 있는 node 이미지를 사용하고, 빌드 컨텍스트에 있는 모든 파일을 복사한다.
해당 Dockerfile이 있는 경로로 이동하여 (cd 명령어 사용) 다음 명령어로 Dockerfile-build 파일명을 도커파일로 사용하여 이미지를 빌드한다.
docker build -f Dockerfile-basic -t buildapp:basic .
node.js가 컴퓨터에 설치되어 있지 않거나, 다른 버전이 설치되어 있어도 컨테이너 이미지를 통해서 node.js 애플리케이션을 빌드하고 실행시킬 수 있다.
실습2) 도커파일명이 Dockerfile-meta인 파일에 다음과 같이 작성한다.
FROM node:14
WORKDIR /app
COPY . .
RUN npm install
USER node
EXPOSE 3000
CMD ["npm", "start"]
COPY 경로를 . .으로 바꾼 이유는, WORKDIR에서 경로를 /app으로 지정해 놓으면 그 이후에 나오는 모든 명령어들은 /app에서 실행하기 때문이다. 이후에 사용되는 지시어에 영향을 주기 때문에 FROM 지시어 이후 바로 작성하는 것이 좋다. WORDIR로 특정 경로를 지정해 놓으면 기존의 node.js 이미지에 있던 파일 시스템과 섞이지도 않고 폴더로 관리할 수 있다.
이미지를 빌드한다.
docker build -f Dockerfile-meta -t buildapp:meta .
위에서 만든 이미지(buildapp:meta)로 컨테이너를 실행한다.
docker run -d -p 3000:3000 --name buildapp-meta buildapp:meta
localhost:3000 으로 접속하면 다음과 같은 화면이 보인다.
실습3) 도커파일명이 Dockerfile-arg, Dockerfile-env인 파일에 각각 다음과 같이 작성한다.
Dockerfile-arg
FROM node:14
WORKDIR /app
COPY ./ /app/
RUN npm install
ARG COLOR=red
USER node
EXPOSE 3000
CMD ["npm", "start"]
Dockerfile-env
FROM node:14
WORKDIR /app
COPY ./ /app/
RUN npm install
ENV COLOR=red
USER node
EXPOSE 3000
CMD ["npm", "start"]
두 개의 도커파일을 빌드하고, 컨테이너로 실행한다.
docker build -f Dockerfile-arg -t buildapp:arg .
docker build -f Dockerfile-env -t buildapp:env .
docker run -d --name buildapp-arg -p 3001:3000 buildapp:arg
docker run -d --name buildapp-env -p 3002:3000 buildapp:env
docker ps로 실행을 확인한다.
localhost:3001 (ARG 사용)로 접속하면 기본색인 GREEN으로 적용된 것을 볼 수 있다. ARG 값으로 RED를 지정했지만, ARG는 컨테이너로 실행할 때는 적용되지 않기 때문에 애플리케이션 기본 값인 GREEN 으로 적용되었다.
localhost:3002 (ENV 사용) 로 접속하면 ENV로 설정한 RED로 적용된 것을 볼 수 있다.
실습4) 도커파일명이 Dockerfile-entrypoint인 파일에 다음과 같이 작성한다.
FROM node:14
WORKDIR /app
COPY ./ /app/
RUN npm install
USER node
EXPOSE 3000
ENTRYPOINT ["npm"]
CMD ["start"]
이미지를 빌드한다.
docker build -f Dockerfile-entrypoint -t buildapp:entrypoint .
이미지의 CMD를 list로 덮어씌우며 컨테이너로 실행한다. 결론적으로 실행되는 명령어는 npm list가 된다.
docker run --name buildapp-entrypoint-list buildapp:entrypoint list
다음 명령어는 buildapp:entrypoint 이미지의 CMD를 /bin/bash로 덮어씌우며 컨테이너로 실행한다. ENTRYPOINT에 npm 명령어가 있기 때문에 실제로 실행되는 명령어는 npm bin/bash 로, 잘못된 명령어가 실행된다.
docker run -it --name buildapp-entrypoint-bash buildapp:entrypoint /bin/bash
실습에 사용한 컨테이너들을 삭제한다.
docker rm -f buildapp-meta buildapp-arg buildapp-env buildapp-entrypoint-list buildapp-entrypoint-bash
'Docker' 카테고리의 다른 글
클라우드 네이티브 애플리케이션 (0) | 2024.02.27 |
---|---|
멀티 스테이지 빌드 (0) | 2024.02.27 |
빌드 컨텍스트 (0) | 2024.02.20 |
이미지 커밋과 빌드 (0) | 2024.02.20 |
이미지와 레이어 (0) | 2024.02.19 |