Dockerfile을 작성하고 사용하는 방법에 대해 다룬다.
Docker
Docker는 소프트웨어를 컨테이너라는 단위로 패키징하여 항상 동일한 환경에서 작업을 수행할 수 있도록 한다.
Image vs. Container
이미지는 Dockerfile로부터 생성된 빌드 결과물이라고 할 수 있다. 이러한 이미지를 Run 하는 것으로 실행 상태가 된 것이 컨테이너이다. 이미지는 Dockerfile을 이용해서 공유하거나 Docker Hub에서 미리 빌드된 이미지를 다운로드 받을 수 있다.
Docker는 소프트웨어 개발 및 배포에 용이하여 많이 사용되지만, 해킹을 하는 사람의 입장에서도 유용하게 사용할 수 있다. 자주 사용되는 환경을 이미지로 빌드해두면 필요할 때 빠르게 사용할 수 있다.
Dockerfile
여기서는 본인이 실제 사용 중인 도커파일을 예시로 Dockerfile의 작성법과 자주 사용되는 명령어에 대해 알아본다.
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
ENV LC_CTYPE=C.UTF-8
RUN ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
RUN mkdir -p /setup/config
WORKDIR /setup
RUN apt-get update
RUN apt-get install -y git gcc gettext ssh curl wget gdb zsh python3 python3-pip libffi-dev build-essential libssl-dev make cmake
# oh my zsh
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# powerlevel10k
RUN git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
RUN echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >> ~/.zshrc
RUN chsh -s /usr/bin/zsh
# neovim
RUN git clone https://github.com/neovim/neovim.git && cd neovim && make CMAKE_BUILD_TYPE=RelWithDebInfo && make install
# astronvim
RUN git clone --depth 1 https://github.com/AstroNvim/AstroNvim ~/.config/nvim
COPY init.lua /setup/config/init.lua
COPY .zshrc /setup/config/.zshrc
WORKDIR /home
CMD [ "zsh" ]
- FROM : 베이스 이미지를 지정한다. 이미지 이름과 태그를 지정하여 베이스 이미지를 선택할 수 있다. 만약 빌드 환경에 해당 이미지가 없을 경우 자동으로 도커 허브에서 베이스 이미지를 찾아서 다운로드 한다.
- ARG : 이미지 빌드 시에 사용되는 변수를 지정한다.
DEBIAN_FRONTEND=noninteractive
는 사용자와 상호작용이 필요한 부분을 무시하도록 한다. - ENV : 컨테이너에서 사용되는 환경 변수를 지정한다.
LC_CTYPE=C.UTF-8
는 해당 환경의 로케일을 설정한다. - RUN : CLI 명령을 실행한다. 터미널에서 명령어를 실행하는 것을 생각하면 된다.
- WORKDIR : 작업 디렉토리를 설정한다. 해당 명령어 이후로 실행되는 명령어들은 지정된 디렉토리에서 실행된다.
- COPY : 이미지 외부의 파일을 이미지에 복사한다.
- CMD : 컨테이너를 생성할 때 실행된다.
위 Dockerfile은 ubuntu 22.04에 zsh, neovim을 설치하고 사용 중인 설정 파일들을 이미지 내부에 복사하도록 하였다. 해당 스크립트를 기본으로 하고 추가적으로 필요한 툴을 설치해서 사용한다.
Build & Run
이미지와 컨테이너를 관리하는 작업은 GUI 환경이 있다면 Docker Desktop을 이용해서 더 편리하게 할 수 있다.
Docker 이미지 빌드
docker build -f <path/to/Dockerfile> -t <tag> .
생성된 이미지 실행
docker run --name <container name> -it <tag>
실행 중인 컨테이너를 정지하거나 다시 실행
docker start <container id or name>
docker stop <container id or name>
실행 중인 컨테이너에 명령 실행
docker exec -it <container id or name> <command>
존재하는 모든 이미지 확인
docker images -a
존재하는 모든 컨테이너 확인
docker ps -a
호스트에서 컨테이너로 파일 복사
docker cp <path/to/file> <container id or name>:<path/in/container>