ubuntu 이미지로 컨테이너를 만들어서 git, python을 설치했을 때, 이 환경을 그대로 백업하거나 이미지로 만들어 배포하고 싶을 때 commit을 사용한다. 이 git과 python을 설치한 ubuntu 컨테이너를 commit하면 ubuntu+git+python이 설치된 이미지가 만들어지는 것이다.
실습 방법
- ubuntu 이미지를 실행해서 컨테이너를 생성한다.
- 실행된 ubuntu 컨테이너에 git을 설치한다.
- ubuntu + git이 설치된 컨테이너를 commit해서 새로운 이미지를 생성한다.
- 새로운 이미지로 각각 다른 두개의 컨테이너를 생성한다.
- 한 컨테이너에는 python을 설치한다.
- 또 다른 컨테이너에는 node.js를 설치한다.
# ubuntu 이미지 다운로드
$ docker pull ubuntu
# ubuntu 이미지로 my-ubuntu라는 컨테이너 실행, 실행하자마자 bash 터미널 연결
$ docker run -it --name my-ubuntu ubuntu bash
# apt 갱신
$ apt update
# git 설치
$ apt install git
# 컨테이너 bash 터미널 종료
$ exit
# 커밋하기! => docker commit <컨테이너명> <레포지토리명>:<태그>
$ docker commit my-ubuntu hello:ubuntu-git
# 생성되었는지 확인
$ docker images
레포지토리라길래 Docker hub를 사용해야하는건가 했는데 그냥 로컬 레포지토리 말하는 거였다. 커밋을 하고나면 $ docker images
로 확인했을 때 레포지토리 hello
에 ubuntu-git
이라는 이름의 이미지가 새로 올라간 것을 볼 수 있다. 여기까지 하면 내가 아까 ubuntu에 git을 설치했던 컨테이너로 이미지를 만든 것이다.
이제 이 새로운 이미지로 다시 컨테이너를 만들어서 각각 python과 node.js를 설치해보겠다. 두 컨테이너는 서로 독립된 다른 환경이 될 것이므로 python을 설치한 컨테이너에서는 node.js가 먹지 않을 것이고, node.js를 설치한 컨테이너에서는 python이 먹지 않을 것이다.
# python
$ docker run -it --name python hello:ubuntu-git bash
$ apt update && apt install python
# node.js
$ docker run -it --name nodejs hello:ubuntu-git bash
$ apt update && apt install nodejs
ubuntu + git + python 컨테이너
$ python
은 실행되지만 $ nodejs
는 실행되지 않는다.
ubuntu + git + node.js 컨테이너
$ nodejs
는 실행되지만 $ python
은 실행되지 않는다.
되게 어려운 줄 알았는데 블로그에 설명이 엄청 짧고 많이 없다. 생각보다 간단한거 같으니 무작정 시작
일단 cmd 창에는 vi 에디터가 없어서 Dockerfile을 만들기 위해 vi 에디터 사용이 가능한 ubuntu shell로 이동했다.
$ vi Dockerfile
로 Dockerfile을 만든 후에, 내용은 아래처럼 써줬다. 위에서 ubuntu 이미지 기반 컨테이너에 git을 설치할 때 한줄씩 썼던 커맨드를 파일에 한번에 쓴것이다.
FROM ubuntu # ubuntu 이미지 기반으로
RUN apt update && apt install -y git # apt update를 하고, git을 설치한다.
이 Dockerfile을 빌드하는 명령어는 다음과 같다. Dockerfile은 현재 디렉토리에서 만들었으므로 마지막 인자는 .
이다.
# docker build -t <레포지토리명>:<태그> <Dockerfile이 위치하는 디렉토리>
# -t는 이미지 이름을 지정하는 옵션
$ docker build -t hello:ubuntu-git-2 .
$ docker images
를 쳤을 때 레포지토리 hello에 ubuntu-git-2 라는 태그를 가진 이미지가 새로 만들어진 것을 확인할 수 있다.
Dockerfile을 만들어서 안에 명령어를 다 써놓으면 build 명령어만으로 모든 환경이 구성되니까 편한 거 같긴 하다. 주입식 세뇌당한거 같기도 하고.. 아무튼 commit은 컨테이너 구성을 다 해놓고 백업하는 느낌이라면 Dockerfile은 생성까지 한방에 하는 느낌이다.
이제 대충 느낌이 오는 거 같아서 Dockerfile 명령어 키워드도 한번 정리해보겠다.
FROM <IMAGE_NAME>
RUN <COMMAND>
=> Build 될 때 실행되는 명령어로, 이미지에 반영됨FROM
으로 설정한 이미지에 포함된 /bin/sh 실행파일을 사용한다.RUN
이 실행될 때마다 layer가 생성되어 저장된다.WORKDIR <PATH>
COPY <Host의 복사할 파일 경로> <이미지에서 파일이 위치할 경로>
CMD <COMMAND>
=> Container가 실행되는 시점에 실행되는 명령어로, 컨테이너에 반영됨$ docker run
이나 $ docker start
로 컨테이너가 시작될 때 실행되는 명령어CMD
는 Dockerfile에서 한번밖에 못쓴다.