터칭 데이터
Docker & K8S - 실습 간단한 Hello World 프로그램(1) 본문
node.js로 만든 간단한 프로그램을 단계별로 이미지 빌드부터 최종적으로 다른 서버에서 실행까지 전체 과정을 다뤄보자
1. node.js로 Hello World를 프린트하는 프로그램을 작성합니다.
2. 그 프로그램을 Docker Image로 만듭니다.
3. 만든 이미지를 컨테이너에서 실행합니다.
4. Docker Hub에 로딩합니다.
5. 다른 컴퓨터에서 Pull해 Container에서 실행합니다.
만들려는 프로그램 개요
Node.js로 구성된 초간단 웹 서비스
a. app.js가 전부!
b. 하지만 node 런타임 환경이 필요
보통 이를 실행하려면
a. node app.js
단 node 환경이 설정되어 있어야함!
app.js
console.log("Hello Docker!");
만들려는 프로그램 실행 (Docker 없이)
직접 설치/실행시 순서
a. OS 선택
b. Node 설치
c. 코드 복사
d. 프로그램 실행 (node app.js)
a~d 과정을 Dockerfile에 기술하고 기술한 뒤에는 Docker build 커맨더로 Docker 이미지를 생성 가능
Dockerfile의 생성
node:alpine을 베이스 이미지로 지정, 포맷은 (이미지 이름):(버전 (문자열이거나 숫자거나))
현재 디렉토리 있는 모든 파일들을 (.) app폴더에 복사(/app)
WORKDIR이 없다면 CMD에서 /app/app.js 형태로 적어야 합니다.
CMD에 실행할 명령을 지정합니다.
Docker에게 소프트웨어 설치 명령을 기술
먼저 베이스 이미지를 기술 (FROM)
다음으로 코드 복사
마지막으로 코드 실행
Dockerfile 사용 가능 기타 키워드
ARG:
Docker Image를 만들 때 사용되는 변수 지정. 최종 이미지에는 안 들어감
ENV
컨테이너가 실행될 때 사용되는 환경변수. 최종 이미지에 저장됨
USER
컨테이너를 실행할 때 사용할 유저 ID
EXPOSE
서비스 사용 포트번호
RUN
빌드시 실행되어야하는 명령들이 지정됨 (docker build)
RUN apt-get update && apt-get install -y curl (여러 명령을 &&로 연결해서 지정 가능)
Dockerfile 키워드: CMD vs. ENTRYPOINT (1)
Container가 시작할 때 실행되어야 하는 명령어를 지정하는데 사용 (docker run)
굉장히 흡사한 기능을 제공하지만 우선 순위가 있음
둘다 한 DOCKERFILE에서 여러번 실행되면 각각 마지막 것만 사용됨
아래의 경우 docker run 실행시 동일한 결과가 나옴
둘 모두 마지막으로 지정된 ["command2.sh"]만 실행
일반적으로는 둘 중 하나만 사용하고 가능하다면 CMD 사용을 권장합니다. 둘 모두 사용되는 경우에는 ENTRYPOINT가 우선됩니다.
Dockerfile 키워드: CMD vs. ENTRYPOINT (2)
CMD나 ENTRYPOINT 중 하나만 지정되면 그게 container가 실행될 때 실행
my-image라는 Image의 Dockerfile
FROM debian:buster
COPY ./myproject
RUN apt-get update …
CMD ["./cmd1.sh"]
docker run my-image
=> ./cmd1.sh가 기본으로 실행됨
docker run my-image cmd2.sh와 같이 다른 스크립트를 지정하면 이미지가 처음 컨테이너에서 실행될 때 cmd1.sh 대신에 cmd2.sh가 실행
=> cmd2.sh가 실행됨
The docker run command creates a new container from a Docker image and can optionally run a command within that container.
When you run docker run my-image cmd2.sh, Docker will:
1. Create a new container from the my-image Docker image.
2. Run the cmd2.sh command within the new container.
The CMD ["./cmd1.sh"] instruction in your Dockerfile specifies the default command to run when a container is started from the image. However, if you provide a command at the end of the docker run command (like cmd2.sh in your example), it will override the default CMD specified in the Dockerfile.
So, in your case, docker run my-image cmd2.sh will start a new container from the my-image image and run cmd2.sh instead of ./cmd1.sh.
Please note that cmd2.sh needs to be present in the Docker image, and it should have the appropriate permissions to be executable. If cmd2.sh is not found in the Docker image, you will get an error.
Dockerfile 키워드: CMD vs. ENTRYPOINT (3)
둘이 한 DOCKERFILE에서 같이 지정가능함
둘이 같이 사용되면 ENTRYPOINT가 기본 명령이 되고 CMD가 인자를 제공
CMD에 적힌 값들이 ENTRYPOINT에 적힌 스크립트가 실행될 때 파라미터로 들어갑니다.
ENTRYPOINT는 --entrypoint 옵션을 통해서만 덮어쓰기가 가능
my-image
FROM debian:buster
COPY ./myproject
RUN apt-get update …
ENTRYPOINT ["entrypoint.sh"]
CMD ["param1", "param2"]
docker run my-image
=> entrypoint.sh param1 param2
그냥 실행하면 CMD의 파라미터 값들이 지정
docker run my-image cmd2
=> entrypoint.sh cmd2
여러 CMD 값 중 특정 ENTRYPOINT의 스크립트에 사용될 파라미터를 지정 가능
docker run --entrypoint="/cmd3.sh” my-image
The docker run --entrypoint command allows you to override the ENTRYPOINT specified in the Dockerfile.
In your Dockerfile, ENTRYPOINT ["entrypoint.sh"] is set, which means that entrypoint.sh is the default executable that will be run when a container is started from this image.
However, when you run docker run --entrypoint="/cmd3.sh" my-image, Docker will:
1. Create a new container from the my-image Docker image.
2. Override the default ENTRYPOINT with /cmd3.sh.
3. Run /cmd3.sh as the main command of the container.
Please note that /cmd3.sh needs to be present in the Docker image, and it should have the appropriate permissions to be executable. If /cmd3.sh is not found in the Docker image, you will get an error.
Also, note that the CMD instruction in the Dockerfile provides default arguments to the ENTRYPOINT. If you override the ENTRYPOINT, the CMD values are ignored unless the new ENTRYPOINT is designed to use them.
CMD or ENTRYPOINT?
최대한 CMD만 사용
ENTRYPOINT를 사용하면 실행시 타이핑을 덜 할 수 있음
파라미터를 지정해주면 되기 때문이지만 감춰지기 때문에 오히려 혼란을 줄 수 있음
요약:
1. ENTRYPOINT가 있으면 CMD 값이 파라미터로 실행됨
2. 아니면 CMD가 실행됨
Dockerfile 더 살펴보기: Airflow 예
FROM python:3.7-slim-buster
ENV DEBIAN_FRONTEND noninteractive
ARG AIRFLOW_USER_HOME=/usr/local/airflow
ARG AIRFLOW_VERSION=1.10.9
(ENV와 ARG 모두 Image 빌드에 사용되지만 ARG는 ENV와 달리 이미지에 최종 저장됨)
COPY config/airflow.cfg ${AIRFLOW_USER_HOME}/airflow.cfg
(airflow.cfg를 ${AIRFLOW_USER_HOME}아래에 airflow.cfg라는 파일로 복사)
RUN chown -R airflow: ${AIRFLOW_USER_HOME}
(빌드할 때 실행되는 명령)
EXPOSE 8080 5555 8793
USER airflow
WORKDIR ${AIRFLOW_USER_HOME}
ENTRYPOINT ["/entrypoint.sh"]
CMD ["webserver"]
(=> /entrypoint.sh webserver)
Docker Image 생성
명령 입력시 hello-world-docker라는 이름의 이미지가 현재 디렉토리에 있는 Dockerfile을 통해 만들어집니다. 온점(.)은 Dockerfile이 현재의 위치인 여기 있다는 의미이며 그래서 맨 뒤에 온점(.)을 꼭 붙이셔야 합니다. 만일 다른 디렉토리에 있는 Dockerfile이라면 그에 맞춰 경로(path)를 지정합니다.
Docker Image의 이름은 hello-world-docker가 됩니다.
Docker Image 확인
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world-docker latest cb6c63816878 22 minutes ago 179MB
태그를 별도로 지정하지 않으면 TAG로 latest가 붙습니다.
Docker Container로 실행
$ docker run hello-world-docker # docker run을 Dockerfile에서 CMD
Hello Docker! # 명령이 실행됨
만일 이 이미지를 다른 컴퓨터에서 실행하고자 한다면?
Docker Registry (예를 들면 Docker hub)으로 먼저 등록
'Docker & K8S' 카테고리의 다른 글
Docker & K8S - IMAGE와 TAG 보충 설명 (0) | 2023.12.18 |
---|---|
Docker & K8S - 실습 간단한 Hello World 프로그램(2) (0) | 2023.12.18 |
Docker & K8S - Docker 프로그램 개발 프로세스 (0) | 2023.12.18 |
Docker & K8S - Docker 설치 (0) | 2023.12.18 |
Docker & K8S - Virtual Machines vs. Docker Containers (0) | 2023.12.18 |