Docker의 핵심 개념인 가상화부터 알아보자
개발을 진행한 Local 환경과 Production 서버 환경이 다른 경우가 있다.
예를 들어 local은 window이지만 서버는 linux라면 모든 설치가 그 환경에 맞게 다르게 진행되어야 한다.
또한 Local 환경과 서버가 같은 OS를 사용해도, 서버에서 올바르게 작동하지 않을 수도 있다.
그래서 해결책으로는
다양한 설정은 readme에 기록하고 항상 실행하도록 하는 방법이 있지만
이것도 역시 사람이 하는 것이기 때문에 오류가 날 수 있으며, 운영하는 서버가 많아진다면 그것을 일일히 업데이트를 해줘야 한다.

그럼 서버 환경까지 모두 한번에 소프트웨어화 하는 방법이 없을까?
이런 고민을 해결하는 것이 가상화이다!!
개발(Local)과 운영(Production) 서버의 환경 불일치가 해소할 수 있고,
어느 환경에서든 동일한 환경으로 프로그램을 실행할 수 있다.

docker 등장 전에 가상화 기술로 vm이 사용되었다.
VM이란 호스트 머신이라고 하는 실제 물리적인 컴퓨터 위에,
OS를 포함한 가상화 소프트웨어를 두는 방식이다!
예를 들어, 호소트 머신이 window인데 window에서 linux를 실행하는 것이다.
GCP의 Compute Engine 또는 AWS EC2가 이런 개념을 활용한다.

Computing 서비스를 통해 사용자에게 동일한 컴퓨팅 환경 제공
하지만 vm도 단점이 있다.
OS 위에 OS를 하나 더 실행시키는 점에서 VM은 굉장히 리소스를 많이 사용한다는 단점을 갖고 있다.
이러한 단점을 해결해볼까?
Container : VM의 무거움을 크게 덜어주면서, 가상화를 좀 더 경량화시키는 프로세스
이 컨테이너 기술로 가상화를 더욱 빠르고 가볍게 할 수 있게 되었다.
Container 기술을 쉽게 사용할 수 있도록 나온 도구가 바로 Docker이다!!

docker를 피시방으로 이해할 수 있다.
피시방에서 컴퓨터를 재부팅하면 pc방에서 설정해둔 형태로 다시 복구 되는 느낌처럼
docker도 이미지를 만들어 재부팅하면 docker image의 상태로 실행된다.

다른 사람이 만든 소프트웨어를 가져와서 바로 사용할 수 있다!
다른 사람이 만든 소프트웨어 : docker image
예) my sql이나 jupyter를 docker에서 실행!
자신만의 이미지를 만들면 다른 사람에게 공유할 수 있다!
원격 저장소에 저장하면 어디서나 사용이 가능하다.
원격 저장소 : Container Registory
도커 공식 홈페이지에서 내 운영체제에 맞는 Docker desktop을 설치

작동이 중단 된 컨테이너는 docker ps-a 명령어로 확인할 수 있다.
docker rm은 멈춘 컨테이너만 삭제할 수 있지만 docker rm “컨테이너이름(ID)” -f로 실행 중인 컨테이너도 삭제가 가능하다.
dockerhub에서 공개된 다양한 이미지를 다운받을 수 있다.
Docker Container 내부는 특별한 설정이 없으면 컨테이너를 삭제할 때 파일이 사라진다.
Host와 Container와 파일 공유가 되지 않기 때문이다.
이때 Volume Mount를 진행 하면 Host와 Container의 폴더가 공유된다.
예시)
docker run -it -p 8888:8888 -v/some/host/folder/for/work:/home/jovyan/workspacejupyter/minimal-notebook
공개된 이미지가 아니라 개인 이미지를 만들고 싶다면 아래와 같이 해보자!
프로젝트 setting

pytorch 코드 및 docker file 작성
pytorch 코드는 우리가 모델을 돌릴때 쓰는 코드들을 의미하고
docker파일은 Docker Image를 빌드하기 위한 정보가 저장된 파일이다.

그 외에 Docker file에서 사용하는것
docker image build

docker images | grep 02-docker를 하면 빌드된 이미지를 확인할 수 있다.
docker run “이미지이름:태그”
이제 방금 만든 이미지를 docker run “이미지이름:태그”를 통해 실행해보면 된다!
이미지를 다 만들었다면 인터넷에 업로드하면 된다!
Container Registry에 Docker Image Push
Container Registry: Docker hub, GCP GCR, AWS ECR등
어떤 레지스트리 서비스를 사용했는지에 따라 어떤 클라우드 서비스로 배포할지가 정해진다. (지금은 docker를 이용했으니 dockerhub!)
ML 프레임워크/ 모델이 들어간 도커 이미지는 사이즈가 매우 클 수 밖에 없다.
하지만 이렇게 사이즈가 크게 되면
작은 base image 선정해서 사용하기
자기 환경에 맞는 알맞는 base image를 선정해서 효율적으로 사용해야 한다.

multi stage build 활용하기
도커 이미지를 효율적으로 작성하기 위한 방법으로
컨테이너 이미지를 만들며 빌드엔 필요하지만 최종 컨테이너 이미지엔 필요 없는 내용을 제외하며 이미지를 생성 하는 방법이다.

여러 Docker Image를 실행할 수 있는 Docker Compose에 대해 알아보자
하나의 Docker Image가 아니라 여러 Docker Image를 동시에 실행 하고 싶다면?
혹은 A Image로 Container를 띄우고, 그 이후에 B Container를 실행 해야 하는 경우
(A는 Database고 B는 웹 서비스인 경우)
docker run할 때 옵션이 너무 다양하고, Volume Mount를 하지 않았다면 데이터가 모두 날라간다.
그 해결책이 바로 docker compose이다!

위의 코드는 app 컨테이너와 db 컨테이너를 실행시키는 내용이다
version : Docker Compose 버전
services : 실행할 컨테이너 정의. 각 서비스는 하나의 컨테이너로 세부 설정을 저장
db, app서비스가 존재
image : 이미지 명시
environment : 환경 변수
ports : 포트 설정
depends_on : 여기에 명시된 서비스가 뜬 이후에 실행
restart : 컨테이너 재실행 정책
volumes : 볼륨정의. 호스트와 컨테이너의 저장소를 지정
secrets : 보안이 필요한 데이터 전달
configs : 컨테이너에 사용할 config 파일
command : 컨테이너가 시작될 때 실행할 명령 지정
Docker Image 일괄 실행 : docker-compose up
docker-compose.yml파일을 파싱하여 Container 실행
Docker-compose up -d : 백그라운드에서 실행하기 (docker run -d와동일)
Docker-compose down : 서비스 중단 (컨테이너, 볼륨 등 삭제)
Docker-compose logs <서비스명> : 로그확인
docker-compose up이 완료되면 다음처럼 docker ps 명령어나 docker-compose ps 명령어로 현재 실행되고 있는 컨테이너를 확인할 수 있다.
