본문 바로가기

회고록(TIL&WIL)

TIL 2022.07.11 Docker

Docker

설치 후 실행하여 왼쪽아래 녹색이 떠야 docker 명령어들을 사용할 수 있다.

docker에서 application 실행

docker run [options] {image_name} [command]

ex ) docker run -d -p 80:5000 psb6604/docker-memo:version1

-d : 백그라운드에서 실행되도록

-p 포트 번호 연결(80으로하면 url창에 포트번호입력하지 않아도됨)

dockerhub에 연결 시 이미지이름을 똑같이 지어줘야함 ( : )뒤에는 태그 명

 

docker container 확인

docker ps

docker container 멈추기

docker stop {container_id|conatinaer_name}

docker kill {container_id|conatinaer_name}

docker container 삭제하기

docker rm {container_id}

실행중인 container에서 명령어 실행하기

docker exec [options] {container_id|container_name} [command]

docker container 되살리기

docker restart {container_id|container_name}

Docker image를 만들기 위해서는 Dockerfile이 필요합니다.

# dockerfile
FROM python:3.8

ADD requirements.txt .

RUN pip install -r requirements.txt

ADD templates templates

ADD app.py .

CMD ["python", "app.py"]

 FROM - Docker image를 생성할 때 기본으로 사용할 base image를 적는 부분입니다.

 ADD - src dst 호스트 머신에 있는 파일이나 폴더를, dst라는 위치에 저장합니다.

 RUN  script - script를 실행합니다

CMD - 생성된 docker image를 실행할 때 자동으로 실행되는 커맨드 입니다

 

Docker image build하기

docker build [OPTIONS] PATH

ex ) docker build -t docker-memo:version1 .

-t 옵션을 사용하면 image에 원하는 이름을 붙일 수 있습니다. {image_name}:{tag} 의 형태로 사용하며, {tag}를 붙이지 않을경우 자동으로 latest가 됩니다.

 

 ( . ) 은 docker build를 어느 위치에서 실행할 것인지 정의합니다. 이 위치에 따라 ADD 커맨드에서 호스트의 파일 위치를 사용하는게 바뀔 수 있습니다.

 

Docker image 목록 확인하기

docker images

Docker image는 한번 생성한 다음에는 바뀌지 않아요! 새로운 코드를 담기 위해서는 새로운 이미지를 생성해주어야 합니다.

docker build . -t docker-memo:version2

-t 옵션을 사용할 때 동일한 image_name:tag 를 사용할경우 override되게 된다.

 

DockerHub

Docker 이미지 업로드하기

먼저 repository를 만든 후에 도커 이미지의 이름을 repository와 동일하게 만들어주어야 합니다.

docker build -t {user_id}/docker-memo:version2 .

docker hub에 로그인

docker login
# 후에 나오는 username, password에 치면 됩니다!

docker image push 하기

docker push psb6604/docker-memo:version2

Docker 이미지 삭제하기

docker rmi psb6604/docker-memo:version2

Docker 이미지 pull 하기

docker pull psb6604/docker-memo:version2

docker 로 mongoDB 실행하기

docker run --name mongo_db -p 27017:27017 -d mongo

 

Docker named volume을 사용해서 DB데이터를 유지하기

named volume 생성

docker volume create memo

named volume에 대한 정보 확인

docker volume inspect memo

mongodb에 named volume 을 연결

docker run -p 27017:27017 -v memo:/data/db mongo

mongo 기본 포트 27017 사용

-v 를 통해서 사용할 volume ( : ) 데이터가 저장되는 경로 앞서 실행해뒀던 mongo container

 

volume 확인

docker volume ls

 

Docker bind mount

내가 원하는 volume을 docker container 내의 volume에 연결하는 기능

docker run -v {host_path}:{container_path} <docker_image>
docker run -v "$(pwd)/templates:/templates" -p 80:5000 psb6604/docker-memo:version2
docker  명령어가 실행되는 위치는 항상 프로젝트 폴더여야한다!

Docker network 

docker network 생성하기

docker network create memo

docker network 연결해서 container 실행하기

docker run -d -p 27017:27017 --network memo --network-alias mongo mongo

app.py DB link 변경

# app.py
client = MongoClient('mongo', 27017) # localhost -> mongo로 변경

새로운 이미지 생성

docker build -t psb6604/docker-memo:version3 .

flask app network 연결

docker run -p 5000:5000 --network memo psb6604/docker-memo:version3

network 확인

docker network ls

Docker container의 리소스 사용량 제한하기

memory 제한하기

docker run -i -m 10m python:3.8

cpu 제한하기

docker run -i --cpus=0.5 python:3.8

사용하고 있는 리소스 확인하기

docker stats

 

Docker-compose

여러 컨테이너를 편리하게 실행하기 위해서 만들어둔 도구

YAML 파일을 통해 container를 실행하는데 필요한 옵션을 정의

더 편리하게 실행하는 방법 관리, 버전 관리 등등

# docker-compose.yaml
version: "3.9"

services:
  flask:
    build:
      context: .
    ports:
      - "5000:5000"

docker-compose.yaml이라는 이름으로 만들면 docker-compose command를 사용할 때 기본으로 사용됩니다.

맨 위에 version은 docker-compose의 스키마의 버젼을 뜻합니다.

services 밑에 container의 정의를 적어서 사용합니다.

build를 적어두면 이미지를 빌드하여 사용합니다.

 

docker-compose로 container 띄우기

docker-compose up -d

docker-compose로 container 삭제하기

docker-compose down

 

docker-compose는 여러개의 application을 지원하기 위해서 만들어 둔 것이기 때문에 따로 한 파일에 정의를 한다면 기본적으로 같은 network를 사용하게 됩니다.

# docker-compose.yaml
version: "3.9"

services:
  flask:
    build:
      context: .
    ports:
      - "5000:5000"
  mongo:
    image: mongo:latest
    ports:
      - "27017:27017"

 

docker-compose에서는 bind mount, named volume을 모두 지원

# docker-compose.yaml
version: "3.9"
services:
  flask:
    build:
      context: .
    volumes:
      - ./templates:/templates
    ports:
      - "5000:5000"
  mongo:
    image: mongo:latest
    volumes:
      - mongo:/data/db/
    ports:
      - "27017:27017"

volumes:
  mongo:

 

사용하지 않는 docker 리소스 정리하기

docker rm container_id
docker rmi image_id
docker network rm network_id
docker volume rm volume_id
docker system prune

Docker image 축소하기 - 작은 base image 사용하기

  • 다양한 종류의 tag가 존재하는데 대표적으로
    • alpine
      • 작고, 보안에 집중한 alpine-linux를 기반으로 만들어진 image
      • 보통 모든 이미지들중에서 가장 작음 (python:3.8-alpine기준 16.05MB)
      • python기준으로 봤을 때, pip install을 할 때 불리한 점이 있음
    • buster, jessie, stretch
      • debian에서 만든 linux를 기반으로 만들어진 image
      • buster, jessie, stretch는 os의 codename입니다. (링크)
      • python:3.8과 python:3.8-buster는 동일합니다. (python:3.8기준 332.17MB)
    • slim
      • 실행에 필요한 환경만 만들어둔 image
      • 이미지가 기본이미지에 비해서는 작음 (python:3.8 기준 41.11MB)
      • 보통 python 실행환경에서 가장 많이 쓰이는 이미지
# dockerfile
FROM python:3.8-slim

ADD requirements.txt .

RUN pip install -r requirements.txt

ADD templates templates

ADD app.py .

CMD ["python", "app.py"]

Docker image 축소하기 - multistage build 활용하기

Dockerfile 한 개에 여러개의 FROM 구문을 두는 방식으로, 각 command를 실행하는 과정에서 생성된 것 중 필요한 것만 가져와서 새 이미지를 생성하게 할 수 있습니다.

 

FROM python:3.8-slim AS builder

ADD requirements.txt requirements.txt

RUN pip install -r requirements.txt

FROM python:3.8-slim-buster
COPY --from=builder /user/local/lib/python3.8/site-packages /user/local/lib/python3.8/site-packages

ADD templates templates

ADD app.py .

CMD ["python", "app.py"]