반응형
도커 이미지란?
- Docker 이미지는 베이스 이미지에 필요한 프로그램과 라이브러리, 소스를 설치한 뒤 파일 하나로 만든 것을 말한다.
- 베이스 이미지란 리눅스 배포판의 유저랜드만 설치된 파일을 뜻한다.
- 유저랜드란 OS는 메모리 사용을 기준으로 커널 공간과 유저 공간으로 나눌 수 있는데, 유저 공간에서 실행되는 실행 파일과 라이브러리를 유저랜드라고 한다.
도커파일(Dockerfile)이란?
- Dockerfile은 Docker 이미지 설정 파일로, Dockerfile에 설정된 내용대로 이미지를 생성한다.
- Dockerfile은 <명령> <매개 변수> 형식으로 작성한다. 명령은 대소문자를 구분하지 않지만 보통 대문자로 작성한다.
# 우분투 22.04 기반 nginx 서버 설치한 Docker 이미지 생성 예제
FROM ubuntu:22.04 # FROM : 어떤 이미지를 기반으로 할지 설정
MAINTAINER Foo Bar <foo@bar.com> # MAINTAINER : 생성된 이미지의 개발자 정보
RUN apt update # RUN : 셸 스크립트 혹은 명령을 실행
RUN apt install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
RUN chown -R www-data:www-data /var/lib/nginx
VOLUME ["/data", "/etc/nginx/site-enabled", "/var/log/nginx"] # VOLUME: 호스트와 공유할 디렉터리 목록
WORKDIR /etc/nginx # WORKDIR: CMD에서 설정한 실행 파일이 실행될 디렉터리
CMD ["nginx"] # CMD: 컨테이너가 시작되었을 때 실행할 실행 파일 또는 셸 스크립트
EXPOSE 80 # EXPOSE: 호스트와 연결할 포트 번호
EXPOSE 443
FROM
- FROM은 어떤 이미지를 기반으로 이미지를 생성할지 설정한다.
- Dockerfile로 이미지를 생성할 때는 항상 기존에 있는 이미지를 기반으로 생성하기 때문에 FROM은 반드시 설정해야 한다.
- Dockerfile에서 명령은 항상 FROM으로 시작해야 하며, FROM이 없거나 FROM 앞에 다른 명령이 있으면 이미지가 생성되지 않는다.
FROM ubuntu # latest 버전
FROM ubuntu:22.04
MAINTAINER
- MAINTAINER는 이미지를 생성한 사람의 정보를 설정한다.
MAINTAINER <작성자 정보>
MAINTAINER Hong, Gildong <gd@yuldo.com>
RUN
- RUN은 FROM에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행합니다.
- RUN으로 실행한 결과가 새 이미지로 생성되고, 실행 내역은 이미지의 히스토리에 기록된다.
- 셸 스크립트 구문을 사용할 수 있으며, FROM으로 설정한 이미지에 포함된 /bin/sh 실행 파일을 사용하게 되며 /bin/sh 실행 파일이 없으면 사용할 수 없다.
- RUN으로 실행한 결과는 캐시되며 다음 빌드 때 재사용한다. 캐시된 결과를 사용하지 않으려면 docker build 명령에서 --no-cache 옵션을 사용하면 된다.
RUN <명령>
RUN apt install -y nginx # 셸 스크립트로 실행
RUN echo "Hello Docker" > /tmp/hello
RUN curl -sSL https://go.dev/dl/go1.19.2.src.tar.gz | tar -v -C /usr/local -xz
RUN git clone https://github.com/docker/docker.git
RUN ["<실행 파일>", "<매개 변수1>", "<매개 변수2>"] # 셸 없이 바로 실행
RUN ["apt", "install", "-y", "nginx"]
RUN ["/user/local/bin/hello", "--help"]
CMD
- CMD는 컨테이너가 시작되었을 때 스크립트 혹은 명령을 실행한다. 즉 docker run 명령으로 컨테이너를 생성하거나, docker start 명령으로 정지된 컨테이너를 시작할 때 실행된다.
- CMD는 Dockerfile에서 한 번만 사용할 수 있다.
CMD <명령> # 셸 명령어로 실행
CMD touch /home/hello/hello.txt
CMD ["<실행 파일>", "<매개 변수1>", "<매개 변수2>"] # 셸 없이 바로 실행할 때 매개 변수 설정
CMD ["mysqld", "--datadir=/var/lib/mysql", "--user=mysql"]
- ENTRYPOINT에 설정한 명령에 매개 변수를 전달하여 실행한다. Dockerfile에 ENTRYPOINT가 있으면 CMD는 ENTRYPOINT에 매개 변수만 전달하는 역할을 하므로, CMD 독자적으로 파일을 실행할 수 없게 된다.
CMD ["<매개 변수1>", "<매개 변수2>"] # ENTRYPOINT를 사용할 때
ENTRYPOINT ["echo"]
CMD ["hello"]
ENTRYPOINT
- ENTRYPOINT는 CMD와 같이 컨테이너가 시작되었을 때 스크립트 혹은 명령을 실행한다. 즉 docker run 명령으로 컨테이너를 생성하거나, docker start 명령으로 정지된 컨테이너를 시작할 때 실행된다.
- ENTRYPOINT는 Dockerfile에서 단 한번만 사용할 수 있습니다.
ENTRYPOINT <명령> # 셸(/bin/sh)로 명령 실행
ENTRYPOINT touch /home/hello/hello.txt
ENTRYPOINT ["<실행 파일>", "<매개 변수1>", "<매개 변수2>"] # 셸 없이 바로 실행
ENTRYPOINT ["/home/hello/hello.sh", "--hello=1", "--world=2"]
- CMD와 ENTRYPOINT는 컨테이너가 생성될 때 명령이 실행되는 것은 동일하지만 docker run 명령에서 동작 방식이 다르다.
- 컨테이너를 생성할 때 docker run <이미지> <실행할 파일> 형식인데, CMD로 설정시 docker run 명령에서 실행할 파일을 설정하면 CMD는 무시된다. ENTRYPOINT는 docker run 명령에서 실행할 파일을 설정하면 ENTRYPOINT 무시되지 않고, 실행할 파일 설정 자체를 매개 변수로 받아서 처리한다.
EXPOSE
- EXPOSE는 호스트와 연결할 포트 번호를 설정하며, docker run 명령의 --expose 옵션과 동일하다.
- EXPOSE는 호스트와 연결만 할 뿐 외부에 노출은 되지 않는다. 포트를 외부에 노출하려면 docker run 명령의 -p, -P 옵션을 사용해야 한다.
EXPOSE <포트 번호>
EXPOSE 80 443
ENV
- ENV는 환경 변수를 설정하며, ENV로 설정한 환경 변수는 RUN, CMD, ENTRYPOINT에 적용된다.
- 환경 변수를 사용할 때는 $를 사용한다.
ENV <환경 변수> <값>
ENV HELLO 1234
CMD echo $HELLO
- 환경 변수는 docker run 명령에서도 설정할 수 있으며, -e <환경 변수>=<값> 형식이다. -e 옵션은 여러 번 사용할 수 있고, --env 옵션과 같다.
$ sudo docker run -e HELLO=4321 example
4321
ADD
- ADD는 파일을 이미지에 추가한다.
- <복사할 파일 경로>는 컨텍스트 아래를 기준으로 하며 컨텍스트 바깥의 파일, 디렉터리나 절대 경로는 사용할 수 없다.
- <복사할 파일 경로>는 파일뿐만 아니라 디렉터리도 설정할 수 있으며, 디렉터리를 지정하면 디렉터리의 모든 파일을 복사한다. 또한, 와일드카드를 사용하여 특정 파일만 복사할 수 있으며, 인터넷에 있는 파일의 URL을 설정할 수 있다.
- <이미지에서 파일이 위치할 경로>의 마지막에 /가 있으면 디렉터리가 생성되고 파일은 그 아래에 복사된다.
- <이미지에서 파일이 위치할 경로>는 항상 절대 경로로 설정해야 한다. 그리고 마지막이 /로 끝나면 디렉터리가 생성되고 파일은 그 아래에 복사된다.
ADD <복사할 파일 경로> <이미지에서 파일이 위치할 경로>
ADD hello-entrypoint.sh /entrypoint.sh
ADD hello-dir /hello-dir
ADD zlib-1.2.8.tar.gz /
ADD hello.zip /
ADD http://example.com/hello.txt /hello.txt
ADD *.txt /root/
COPY
- COPY는 파일을 이미지에 추가한다. ADD와는 달리 COPY는 압축 파일을 추가할 때 압축을 해제하지 않고, 파일 URL도 사용할 수 없다.
COPY <복사할 파일 경로> <이미지에서 파일이 위치할 경로>
COPY hello-entrypoint.sh /entrypoint.sh
COPY hello-dir /hello-dir
COPY zlib-1.2.8.tar.gz /zlib-1.2.8.tar.gz
COPY *.txt /root/
VOLUME
- VOLUME은 디렉터리의 내용을 컨테이너에 저장하지 않고 호스트에 저장하도록 설정한다.
VOLUME <컨테이너 디렉터리> 또는 VOLUME ["컨테이너 디렉터리 1", "컨테이너 디렉터리2"]
VOLUME /data
VOLUME ["/data", "/var/log/hello"]
- VOLUME으로 /data처럼 바로 경로를 설정할 수도 있고, ["/data", "/var/log/hello"]처럼 배열 형태로 설정할 수도 있지만, 호스트의 특정 디렉터리와 연결할 수는 없다. 데이터 볼륨을 호스트의 특정 디렉터리와 연결하려면 docker run 명령에서 -v 옵션을 사용해야 한다.
-v <호스트 디렉터리>:<컨테이너 디렉터리>
$ sudo docker run -v /root/data:/data example
USER
- USER는 명령을 실행할 사용자 계정을 설정하며, RUN, CMD, ENTRYPOINT에 적용된다.
- 중간에 USER를 설정하면 중간에 사용자를 바꿀 수 있다.
USER <계정 사용자명>
USER nobody
RUN touch /tmp/hello.txt
USER root
RUN touch /hello.txt
ENTRYPOINT /hello-entrypoint.sh
WORKDIR
- WORKDIR은 RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리를 설정한다.
- 중간에 다른 디렉터리를 설정하여 실행 디렉터리를 다시 바꿀 수 있다.
WORKDIR <경로>
WORKDIR /root
RUN touch hello.txt
WORKDIR /tmp
RUN touch hello.txt
- WORKDIR은 절대 경로 대신 상대 경로도 사용할 수 있다. 상대 경로를 사용하면 먼저 설정한 WORKDIR의 경로를 기준으로 디렉터리를 변경하며, 최초 기준은 / 다.
WORKDIR /root
RUN touch hello.txt
WORKDIR /tmp
RUN touch hello.txt
ONBUILD
- ONBUILD는 생성한 이미지를 기반으로 다른 이미지가 생성될 때 명령을 실행한다.
- 최초에 ONBUILD를 사용한 상태에서는 아무 명령도 실행하지 않지만, 다음 번에 이미지가 FROM으로 사용될 때 실행할 명령을 예약하는 기능이라 할 수 있다.
ONBUILD <Dockerfile 명령> <Dockerfile 명령의 매개 변수>
ONBUILD RUN touch /hello.txt
ONBUILD ADD world.txt /world.txt
이미지 생성하기
- Dockerfile을 작성했으면, Dockerfile이 저장된 디렉터리에서 아래 명령을 실행 해이미지를 생성할 수 있다.
- --tag 옵션으로 이미지 이름과 태그를 설정할 수 있는데, 이미지 이름만 설정하면 태그는 latest로 설정된다.
$ docker build <옵션> <Dockerfile 경로>
$ docker build --tag hello:0.1 .
이미지 실행하기
- -d 옵션은 컨테이너를 백그라운드로 실행한다.
- -p 80:80 옵션으로 호스트의 80번 포트와 컨테이너의 80번 포트를 연결하고 외부에 노출한다. 이렇게 설정한 뒤 http://<호스트 IP>:80에 접속하면 컨테이너의 80번 포트로 접속된다.
- -v /root/data:/data 옵션으로 호스트의 /root/data 디렉터리를 컨테이너의 /data 디렉터리에 연결한다. /root/data 디렉터리에 파일을 넣으면 컨테이너에서 해당 파일을 읽을 수 있다.
$ docker run <옵션> <이미지 이름/아이디> <실행할 파일>
$ docker run --name hello-nginx -d -p 80:80 -v /root/data:/data hello:0.1
필요 없는 파일 제외하기
- 컨텍스트에서 특정 파일이나 디렉터리를 제외하고 싶을 때는 .dockerignore 파일을 사용하면 된다.
example/hello.txt
example/*.cpp
wo*
*.cpp
.git
.svn
Reference
반응형
'Tool > Docker' 카테고리의 다른 글
도커(Docker) 컨테이너 연결 - 링크, 네트워크, 앰배서더 (0) | 2024.01.19 |
---|---|
도커(Docker) 사용법 - 설치, 권한 설정, Bash, 기본 명령어 (0) | 2024.01.18 |
도커(Docker)란? - 기본 개념 및 배경, 이미지와 컨테이너 의미 (0) | 2024.01.18 |