이전 포스트들에서는 도커 허브 등을 통해 공식 이미지를 사용했습니다. 이번에는 직접 컨테이너를 이용해서 이미지를 생성하는 방법에 대해 알아보겠습니다.
이미지를 만드는 방법은 commit 명령과 Dockerfile을 이용하는 방식 두 가지 방식이 있습니다.
이미지를 만드는 첫 번째 방법은 docker commit 명령을 이용한 방법입니다.
docker commit 컨테이너명 생성할_이미지명
docker commit 명령은 컨테이너의 현재 상태를 반영하여 이미지로 생성합니다. 명령을 사용하는 시점의 컨테이너 상태(파일, 패키지 등)를 반영하기 때문에 동일한 이미지를 만들기 쉽지 않다는 단점이 있습니다.
또한 변경 이력이 제대로 추적되지 않는다는 문제도 있어서 일회성 테스트 용도에만 docker commit 명령을 통한 이미지 생성을 하고 잠시 후에 소개할 Dockerfile 방식을 주로 사용하게 됩니다.
그러면 docker commit 명령을 이용한 이미지 생성 실습을 수행해보겠습니다.
alpine이미지로 컨테이너를 먼저 생성해주세요. 이 컨테이너를 기반으로 이미지 생성 실습을 진행합니다.docker run -it --name alpine-commit-test alpine
다음 명령어를 입력하여 생성한 컨테이너를 이미지로 만들어줍니다. 그리고 docker image ls로 생성한 이미지를 확인합니다.
docker commit alpine-commit-test my-image-ex1
docker image ls
잘 생성되었음을 확인할 수 있습니다.
먼저 Dockerfile이라는 것에 대해 설명하고 이미지 생성 방법을 알아보겠습니다.
Dockerfile은 도커 이미지를 생성하기 위한 스크립트 파일입니다. 즉, 이미지를 생성하기 위한 설정(기반 이미지, OS 등)과 명령에 대한 정보들이 적혀있는 파일입니다.
Dockerfile로 이미지를 생성하기 위해서는 이미지를 생성하는데 필요한 것들이 들어있는 디렉토리에 함께 담아두어야합니다. 예를들어 어떤 프로젝트를 이미지로 만든다고 한다면 해당 프로젝트의 루트(권장) 위치에 Dockerfile을 정의하면 됩니다.
Dockerfile은 기본적으로 다음과 같은 구조를 갖습니다.
FROM 이미지명 #이미지 생성에 사용할 베이스가되는 이미지
COPY 원본_경로 붙여넣을_경로 #이미지 내에 넣을 파일 복사 붙여넣기
RUN 이미지 내에서 실행할 명령어
CMD [컨테이너 시작 시 실행할 명령어]
각 스크립트 줄의 맨앞에 오는 키워드를 인스트럭션(Instructions)라고 부르는데요. 인스트럭션은 이미지 빌드에 사용하기 위한 명령어입니다.
| 인스트럭션 | 용도 | 설명 |
|---|---|---|
FROM | 베이스 이미지 설정 | 베이스 이미지 지정 |
LABEL | 메타데이터 지정 | 이미지 정보 태그 (author, version 등) |
ARG | 빌드 시 변수 | 빌드 타임 변수 정의, --build-arg로 전달 |
ENV | 환경 변수 설정 | 컨테이너 실행 중 사용할 환경변수 정의 |
COPY | 파일/디렉토리 복사 | 호스트에서 이미지로 복사 |
ADD | 파일 복사 및 압축 해제 | COPY와 유사하나 URL 다운로드와 압축 해제 가능 |
WORKDIR | 작업 디렉토리 설정 | 이후 명령이 실행될 기본 디렉토리 지정 |
VOLUME | 데이터 볼륨 설정 | 호스트 또는 익명 볼륨 마운트 지점 정의 |
RUN | 명령어 실행 | 빌드 중 쉘 명령어 실행 (예: 패키지 설치) |
SHELL | 기본 쉘 설정 | RUN 명령어에서 사용할 기본 셸 변경 |
CMD | 기본 실행 명령 | 컨테이너 실행 시 기본 명령어 지정 (재정의 가능) |
ENTRYPOINT | 고정 실행 명령 | 컨테이너 시작 시 무조건 실행할 명령어 |
EXPOSE | 포트 명시 | 문서용으로 컨테이너에서 열 포트 정의 |
USER | 사용자 지정 | 이후 명령을 실행할 사용자 설정 |
STOPSIGNAL | 종료 신호 설정 | 컨테이너 종료 시 사용할 시그널 정의 (예: SIGTERM) |
ONBUILD | 후속 Dockerfile용 예약 명령 | 이 이미지를 상속하는 Dockerfile에서 실행될 명령 예약 |
HEALTHCHECK | 헬스 체크 설정 | 컨테이너가 정상 작동 중인지 확인하는 명령 정의 |
인스트럭션 종류가 많은데요. 우선적으로 FROM, COPY, RUN, CMD 정도만 알아두고 나머지는 필요에 따라 차차 알아가시면 됩니다.
그러면 Dockerfile을 이용해서 이미지 파일을 생성해보겠습니다.
먼저 재료 폴더를 준비해주세요. 저는 C:\Users\사용자 위치에 my-image라는 이름의 폴더를 준비했습니다. 그리고 my-image.txt라는 텍스트 파일(내용은 마음대로)을 하나 만들어주세요.
그리고 해당 폴더 위치에서 Dockerfile을 작성합니다. 이름이 확장자없이 그냥 Dockerfile임에 유의해주세요.
FROM alpine:latest
RUN apk update #apk는 alpine의 패키지 매니저
COPY my-image.txt /my-image.txt
CMD ["sh"]
이 네 줄의 스크립트는 다음 역할을 수행합니다.
FROM alpine:latest: alpine 최신 안정 버전을 기반으로 이미지 생성RUN apk update: 이미지 빌드 시 패키지 목록의 패키지를 최신 버전으로 갱신COPY my-image.txt /my-image.txt: 호스트의 텍스트 파일을 이미지 내로 복사CMD ["sh"]: sh 명령어 수행. 즉, 컨테이너를 시작하면 쉘 실행.그러면 이렇게 재료 폴더에 두 가지 파일이 들어있을 것 입니다.
이제 이 재료 폴더를 가지고 이미지를 생성해보겠습니다.
cd 재료_폴더_경로 #반드시 재료 폴더 경로에 들어가서 이미지 빌드 실행!!!
docker build -t my-image-ex2 . # 공백과 점 반드시 명시!!!
build 명령 마지막의 공백과 점을 반드시 작성해주세요. build 명령을 수행하면 빌드한다고 하면서 cmd에 진행 상태가 나타나게 됩니다. 빌드 완료 후 docker image ls로 확인해봅시다.
Dockerfile로 이미지 생성에 성공했음을 볼 수 있습니다.
다음 명령을 통해 실습 환경을 정리합니다.
docker rmi -f alpine my-image-ex1 my-image-ex2
스크립트를 통해 이미지의 실행 방식을 정의하여 알기 쉽고, Git 등을 통해 변경 이력 추적도 가능하며 동일한 Dockerfile에 대해 동일한 이미지 생성을 보장하기 때문에 Dockerfile을 사용하여 이미지를 생성하는 방식이 권장(및 표준 방식)되고 있습니다.