What am I containerizing?
- 애플리케이션에서 사용하려는 컴포넌트 또는 서비스를 Docker Hub 에서 찾을 수 없기 때문에 혹은 개발중인 애플리케이션을 Dockerize 해서 배포가 쉽도록 만들기 위해 Docker Image 를 사용함
How to create my own image?
- Flask 를 이용한 단순한 웹 애플리케이션에 쓸 이미지를 만든다고 가정했을 때 수동으로 설정해야 한다면 아래와 같은 작업을 수행해야 함
- Ubuntu 같은 운영체제
- apt 명령어로 소스 리포지토리를 업데이트
- 의존성을 설치
- pip 명령어로 Python 의존성을 설치
- 애플리케이션 소스 코드를 복사해 넣은 뒤 flask 명령어로 웹 서버를 가동
Dockerfile
이라는 파일 안에 아래 명령어를 적음
FROM Ubuntu
RUN apt-get update && apt-get -y install python
RUN pip install flask flask-mysql
COPY . /opt/source-code
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run
- 이어서
docker build
명령어로 이미지를 구축하고 이미지의 태그 이름과 함께Dockerfile
을 입력값으로 지정, 이러면 로컬에 이미지가 생성됨docker build . -f Dockerfile -t mmumshad/my-custom-app
- 퍼블릭 Docker Hub Registry 에서 이용할 수 있도록 하려면
docker push
명령어를 실행, 이러면 계정 이름이 이미지 이름이 됨docker push mmumshad/my-custom-app
Dockerfile
FROM Ubuntu
RUN apt-get update && apt-get -y install python
RUN pip install flask flask-mysql
COPY . /opt/source-code
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run
Dockerfile
은 Docker 가 인식하도록 특정 형식으로 작성된 텍스트 파일INSTRUCTION
과ARGUMENT
형식으로 이루어짐FROM Ubuntu
- 컨테이너의 기본 운영체제를 정의
- 모든 Docker Image 는 운영체제 혹은 사전에 운영체제에 기반해 생성한 이미지과 같은 또 다른 이미지에 기반을 둠
RUN apt-get update && apt-get -y install python
RUN
명령어는 Docker 가 기본 이미지에 특정 명령어를 실행하도록 함
COPY . /opt/source-code
COPY
는 로컬 시스템의 파일을 복사해 Docker Image 에 넣음. /opt/source-code
현재 폴더에 있는 애플리케이션 소스코드를/opt/source-code
에 붙여넣는다는 의미
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run
ENTRYPOINT
명령어는 이미지가 컨테이너로 실행될 때 작동할 명령어를 지정
Layered Architecture
- Docker 는 계층형 아키텍처로 이미지를 구축
- 명령어 각 줄이 이전 계층의 변경 사항으로 Docker Image 에 새로운 계층을 생성함
- 계층마다 이전 계층의 변경 사항만을 저장하기 때문에 크기에서도 이를 확인할 수 있음
docker history mmumshad/simple-webapp
을 실행하면 확인 가능
Docker build output
docker build .
실행 시 여러 단계와 작업별 결과를 볼 수 있음- 모든 계층은 캐시에 저장되기 때문에 실패하더라도 해당 단계에서
docker build
를 재실행 가능 - 또한 빌드 프로세스에 새로운 단계를 추가해도 처음부터 다시 빌드할 필요가 없음
- 특히 애플리케이션 소스코드 업데이트는 빈번하기 때문에 빠른 재빌드가 가능
Demo
docker run -it ubuntu bash
apt-get update
apt-get install -y python
apt-get install python-pip
pip install flask
# Copy code to /opt/app.py
FLASK_APP=/opt/app.py flask run --host=0.0.0.0
- Dockerfile 없이 수동으로 실행 할 경우
FROM ubuntu
RUN apt-get update
RUN apt-get install -y python
RUN apt-get install python-pip
COPY app.py /opt/app.py
ENTRYPOINT FLASK_APP=/opt/app.py flask run --host=0.0.0.0
- 위와 같은 Dockerfile 을 만들고
docker build . -t my-simple-webapp
명령어로 이미지 생성 - 이미지 생성 후
docker images
명령어 사용 시my-simple-webapp
이미지가 생성되어있음 docker run my-simple-webapp
실행 시 처음 수동 실행과 같은 결과
Environment Variables
docker run -e APP_COLOR=blue simple-webapp-color
-e
옵션을 통해 컨테이너 내에 환경변수 설정 가능
docker inspect blissful_hopper
docker inspect
를 통해 이미 실행 중인 컨테이너의 환경변수를 찾을 수 있음"Config"
섹션에서 해당 컨테이너가 가진 환경변수 확인 가능
CMD vs ENTRYPOINT
CMD
는 해당 이미지가 기본으로 사용할 명령어- ubuntu 이미지의 경우
CMD ["bash"]
- ubuntu 이미지의 경우
FROM Ubuntu
CMD sleep 5
- 위
Dockerfile
로docker build . -t ubuntu-sleeper
docker run ubuntu-sleeper sleep 10
실행 시 CMD 가sleep 10
으로 덮어씌워짐
FROM Ubuntu
ENTRYPOINT ["sleep"]
ENTRYPOINT
사용 시docker run ubuntu-sleeper 10
로 인자를 전달할 수 있음
즉, CMD 의 경우 명령줄 매개변수가 완전히 대체되는 반면, ENTRYPOINT 의 경우 명령줄 매개변수가 추가됨
FROM Ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]
Dockerfile
을 위와 같이 설정할 경우 (JSON 포맷으로 설정해야 됨)docker run ubuntu-sleeper
실행 시sleep 5
가 실행됨docker run ubuntu-sleeper 10
실행 시sleep 10
가 실행됨docker run --entrypoint sleep2.0 ubuntu-sleeper 10
실행 시sleep2.0 10
가 실행됨