개발할때,서비스운영에 사용하는 서버에 직접들어가서 개발하지않음
Local
환경에서 개발하고,완료되면 Staging서버
,Production
서버에배포
🤔 이 부분에서 생기 는고민:서버 환경까지도 모두 한번에 소프트웨어화 할 수 없을까?
특정 소프트웨어 환경을 만들고,Local,Production서버에서 그대로활용
호스트 머신이라고 하는 실제 물리적인 컴퓨터 위에 OS를 포함한 가상 소프트웨어 둠 -> 무거움.
GCP의 ComputeEngine 는 AWS EC2가 이런 개념을 활용
다른사람이 만든 소프트웨어(Docker Image)를 가져와서 바로 사용할수있음
자신만의 이미지를 만들면 다른 사람에게 공유할 수 있음
docker pull “이미지이름:태그"
:필요한 이미지 다운docker images
:다운받은 이미지 목록 확인docker run “이미지이름:태그"
:이미지를 기반으로 컨테이너 생성docker ps
:실행 중인 컨테이너 목록확인docker exec -it “컨테이너이름(ID)"/bin/bash
:컨테이너에 진입docker stop “컨테이너이름(ID)”
:실행중인 컨테이너를 중지docker rm “컨테이너이름(ID)”
:중지된 컨테이너 삭제그외 docker run
할때 파일을 공유하는 방법
VolumeMount
docker run -it -p 8888:8888-v/some/host/folder/for/work:/home/jovyan/workspace
jupyter/minimal-notebook
docker pull mysql:8
을 통해서 docker image 받습니다.
docker run --name mysql-tutorial -e MYSQL_ROOT_PASSWORD=1234 -d -p 3306:3306 mysql:8
을 통해서 mysql container만듦니다. 각각의 명령어 인자의 의미는 밑에.
docker ps
를 통해서 실제 실행하는 container에 대한 정보를 볼 수 있음
mysql-u root -p
MySQL 프로세스로 들어가면 MySQL쉘 화면이 보임
더 많은 docker image들을 볼려면
https://hub.docker.com/ <- docker hub를 통해서 알아보자~
Dockerfile
작성
FROM
으로 베이스이미지를 지정COPY
로 로컬 내 디렉토리 및 파일을 컨테이너 내부로 복사WORKDIR
로 RUN,CMD등을 실행할 컨테이너 내 디렉토리지정RUN
으로 애플리케이션 실행에 필요한 여러 리눅스 명령어들을 실행CMD
로 이미지 실행시 바로 실행할 명령어를 지정docker build“ Dockerfile이 위치한경로” -t “이미지이름:태그”
으로 이미지빌드docker run“이미지이름:태그”
로 빌드한 이미지를 실행EXPOSE
: 컨테이너 외부에 노출할 포트 지정ENTRYPOINT
:이미지를 컨테이너로 띄울 때 항상 실행하는 커맨드참고로 CMD
와 ENTRYPOINT
, RUN
차이점
CMD
는 기본 명령/인자이며, docker run 시 다른 명령을 넣으면 완전히 대체됩니다.ENTRYPOINT
는 실행할 명령을 확실히 고정하고, CMD나 docker run의 인자들은 ENTRYPOINT 뒤에 추가되는 인자 역할을 하게 됩니다.RUN
은 build 할때 실행구분 | 시점 | 용도 |
---|---|---|
RUN | 빌드 타임(이미지 생성) | 이미지 빌드 과정에서 패키지 설치, 소스 컴파일, 설정 파일 수정 등을 통해 최종 이미지 레이어 생성 |
CMD | 런타임(컨테이너 시작 시) | 컨테이너 시작 시 기본 실행 명령(프로세스) 및 인자 제공. docker run 시 인자로 변경 가능 |
ENTRYPOINT | 런타임(컨테이너 시작 시) | 컨테이너 시작 시 반드시 실행해야 하는 명령을 고정. 인자는 CMD나 docker run 명령어 뒤에 추가로 전달됨 |
해석
docker build -t <빌드할이미지이름:태그이름> “Docker file이 위치한 경로”
ex) docker build-t 02-docker:latest.
--t“이미지이름:태그”
옵션으로 이미지이름과 태그 지정할 수 있음docker run“이미지이름:태그”
방금 만든 이미지 실행함.
이제 우리가 만든 이미지를 인터넷에 업로드!
이를 위해 이미지저장소인 ContainerRegistry에 Docker Image Push
docker login
명령어로 계정을 CLI에 연동
docker tag “기존이미지:태그" “새이미지이름:태그”
docker hub에 올릴 이미지 이름은 내계정ID/이미지이름 형태여야 함
docker push 내계정ID“/이미지이름:태그
ML프레임워크/모델이들어간 도커 이미지는 사이즈가 매우 큼
빌드타임: 이미지 빌드하는 시점에서의 문제
런타임: 도커 이미지 실행 시점의 문제
호스트 머신 디스크
작은 BaseImage 선정해서 사용하기
알맞은 BaseImage를 찾는게 중요
사용할 OS package들만 설치후 사용.디버깅하는 목적으로 필요한 shell 환경도 중요
Multi StageBuild 활용하기
컨테이너 이미지를 만들며 빌드엔 필요하지만 최종컨테이너 이미지엔 필요없는 내용을 제외하며 이미지를 생성하는 방법
예시코드: https://github.com/zzsza/Boostcamp-AI-Tech-Product-Serving/tree/main/03-docker/multi_stage_build
single stage 예시
Runtime을 나누고,COPY-from=build를 통해 build에서 필요한 내용만 추출
용량 1GB -> 168MB로 줄어드는 이유
단일 스테이지 빌드 시에는 python:3.9 이미지를 기반으로, 빌드와 런타임에 필요한 모든 패키지와 라이브러리가 하나의 최종 이미지에 포함됩니다. 이로 인해 빌드 도구, 컴파일러, 캐시, 미사용 패키지 등이 모두 최종 이미지에 남아 용량이 커집니다.
반면 multi-stage 빌드를 사용하면, 빌드에 필요한 도구와 라이브러리는 첫 번째 스테이지에서만 사용되고, 최종 스테이지에는 오직 런타임에 필요한 최소한의 파일들(실행 파일, 라이브러리, 의존성 패키지)만 남게 됩니다
Container를 잘 패키징하기
1) .docker ignore
로필요없는 파일들 제거
2).pt,.pth
파일과 같은 큰 사이즈 asset들은 빌드에서 포함하지 않고,빌드 타임 혹은 컨테이너 시작하는 스크립트에서 다운
3) Dockerfile
안에서 command들의 순서최적화를 통해 캐싱을 최대한 이용
여러 container를 한번에 수행함
docker-compose.yml
파일에 작성db랑 app실행
services
: 실행할 컨테이너정의.각 서비스는 하나의 컨테이너로 세부 설정을 저장image
: 이미지 명시environment
: 환경변수ports
: 포트 설정depends_on
: 여기에 명시된 서비스가 뜬 이후에 실행restart
: 컨테이너 재실행 정책volumes
: 볼륨 정의. 호스트와 컨테이너의 저장소를 지정secrets
: 보안이 필요한 데이터 전달configs
: 컨테이너에 사용할 config 파일command
: 컨테이너가 시작될 때 실행할 명령 지정DockerImage 일괄 실행: docker-compose up
docker-compose up -d
:백그라운드에서 실행하기(docker run-d와동일)
docker-compose down
:서비스중단(컨테이너,볼륨등삭제)
docker-compose logs <서비스명>
:로그확인
참고로docker-compose.yml파일을수정하고docker-composeup을 하면 컨테이너를 재생성하고,서비스를 재시작함