
➡️ 어떠한 프로그램을 다운 받는 과정을 굉장히 간단하게 만들기 위해서이다.

갖고 있는 서버, 패키지 버전, 운영체제 등등에 따라
프로그램을 설치하는 과정 중에 많은 에러들이 발생하고 설치 과정이 다소 복잡하다.


도커는 선택사항
컨테이너를 사용하여 응용프로그램을 더 쉽게 만들고 배포하고 실행할 수 있도록 설계된 도구이며 컨테이너 기반의 오픈소스 가상화 플랫폼이며 생태계이다.
컨테이너란?





항상 도커를 사용할 때는...
1. 먼저 도커 CLI에 커맨드를 입력한다.
2. 그러면 도커 서버 (도커 Daemon)이 그 커맨드를 받아서 그것에 따라 이미지를 생성하든 컨테이너를 실행하든 모든 작업을 하게 된다.

실제로 커맨드를 입력해보기
1. docker run hello-world

설명
- 도커 클라이언트에 커맨드를 입력하니 클라이언트에서 도커 서버로 요청을 보냄
- 서버에서 hello-world라는 이미지가 이미 로컬에 cache가 되어 있는지 확인
- 현재는 없기에 Unable to find image ~ 라는 문구가 2번째 줄에 표시
- 그러면 Docker Hub이라는 이미지가 저장되어 있는 곳에 가서 그 이미지를 가져오고 로컬에 Cache로 보관한다.
- 그 후 이제는 이미지가 있으니 그 이미지를 이용해서 컨테이너를 생성한다.
- 그리고 이미지로 생성된 컨테이너는 이미지에서 받은 설정이나 조건에 따라 프로그램을 실행을 한다.


이제 hello-world 이미지가 캐시가 되어있으니
한번 더 docker run hello-world 하면 어떻게 될까?
1. Unable to find image ~ 라는 문구가 없이 프로그램이 실행됨.
2. 결국은 캐쉬 된 이미지를 이용해서 컨테이너를 만든 후 프로그램을 실행.
지금까지 이미지를 이용해서 컨테이너를 생성한다고 배웠다.
하지만 어떻게 이미지를 이용해 컨테이너를 생성하는지는 다루지 않았다.
이번에는 어떻게 컨테이너가 생성이 되게 되는지 자세히 알아보겠다.

이미지로 컨테이너 만드는 순서
1. Docker 클라이언트에 docker run <이미지> 입력해준다.
2. 도커 이미지에 있는 파일 스냅샷을 컨테이너 하드 디스크에 옮겨 준다.


지금까지 도커 이미지를 항상 도커 허브에 이미 있던 것들만 가져와서 사용했다. 하지만 직접 도커 이미지를 만들어서 사용할 수도 있고 직접 만든 도커 이미지를 도커 허브에 올려서 공유할 수도 있다.
➡️ 어떻게 직접 이미지를 만들 수 있는지 알아보겠다.
간단하게 도커 이미지 다시 복습하기
- 도커 이미지는 컨테이너를 만들기 위해 필요한 설정이나 종속성들을 갖고 있는 소프트웨어 패키지이다.
- 지금까지 해왔듯이 도커 이미지는 Dockerhub에 이미 다른 사람들이 만들어 놓은 것을 이용할 수도 있으며, 직접 도커 이미지를 만들어서 사용할 수도 있고 직접 만든 것을 Dockerhub에 업로드할 수도 있다.
도커 이미지를 이용해서 도커 컨테이너를 생성.
ex) docker create <이미지 이름>
컨테이너는 도커 이미지로 생성한다.
그럼 도커 이미지는 어떻게 생성할까?

Dockerfile을 만드는 법

도커 파일(Docker file)이란 ?
-도커 이미지를 만들기 위한 설정 파일이며, 컨테이너가 어떻게 행동해야 하는지에 대한 설정들을 정의해 주는 곳이다.
도커 파일 만드는 순서 (도커 이미지가 필요한 것이 무엇인지를 생각하기)
- 베이스 이미지를 명시해준다. (파일 스냅샷에 해당)
- 추가적으로 필요한 파일을 다운 받기 위한 몇 가지 명령어를 명시해준다. (파일 스냅샷에 해당)
- 컨테이너 시작 시 실행될 명령어를 명시해준다. (시작 시 실행될 명령어에 해당)
베이스 이미지
-도커 이미지는 여러개의 레이어들로 되어 있다.
그 중에서 베이스 이미지는 이 이미지의 기반이 되는 부분이다.
-레이어는 중간 단계의 이미지라고 생각하면 된다.
실제로 만들면서 배우기!

순서
- 도커 파일을 만들 폴더 하나 만들기 ex) dockerfile-folder
- 방금 생성한 도커 파일 폴더를 에디터를 이용해서 실행
(Visual Studio Code 추천)- 파일 하나를 생성, 이름은 dockerfile
- 그 안에 먼저 어떻게 진행해 나갈지 기본적인 토대를 명시.
- 이제 베이스 이미지부터 실제 값으로 추가.
- 베이스 이미지는 ubuntu를 써도 되고 centos 등을 써도 되지만 hello를 출력하는 기능은 굳이 사이즈가 큰 베이스 이미지를 쓸 필요가 없기에 사이즈가 작은 alpine 베이스 이미지를 사용.
- hello 문자를 출력해주기 위해 echo를 사용하여야 하는데 이미 alpine 안에 echo를 사용하게 할 수 있는 파일이 있기에 RUN 부분은 생략.
- 마지막으로 컨테이너 시작 시 실행될 명령어 echo hello를 적어줌.


FROM RUN CMD 등은 도커 서버에게 무엇을 하라고 알려주는 것이다.
FROM
이미지 생성 시 기반이 되는 이미지 레이어입니다.
<이미지 이름>:<태그> 형식으로 작성
태그를 안 붙이면 자동적으로 가장 최신 것으로 다운 받음
ex) ubuntu:14.04
RUN
도커 이미지가 생성되기 전에 수행할 쉘 명령어
CMD
컨테이너가 시작되었을 때
실행할 실행 파일 또는 셸 스크립트입니다.
해당 명령어는 DockerFile 내 1회만 쓸 수 있습니다
이렇게 해서 도커 파일 만들기는 완성되었다.
이제 이미지는 어떻게 만들어야 하는지 알아보겠다!
완성된 도커 파일로 어떻게 이미지를 생성?
도커 파일에 입력된 것들이 도커 클라이언트에 전달되어서 도커 서버가 인식하게 하여야 한다.
➡️ docker build ./ 또는 docker build .
Build 명령어
-해당 디렉토리 내에서 dockerfile이라는 파일을 찾아서 도커 클라이언트에 전달시켜준다.
-docker build 뒤에 ./ 와 . 는 둘 다 현재 디렉토리를 가리킨다.
docker build . 를 해보면


build 과정 설명 (버전이 업데이트되어서 터미널 실행 결과 다름)
Step 1/2
-alpine 이미지 가져오기 a24bb~ 는 alpine 이미지 아이디
Step 2/2
-임시 컨테이너 생성 후 그 컨테이너에 시작 시 사용할 명령어 포함시키기.
-그런 후 방금 생성 한 임시 컨테이너를 지우고 새로운 이미지 만들기
Step 2/2 자세히 보기
Step 2에 보면 임시 컨테이너를 생성하고 무언가를 하고 다시 지우는데 왜 그렇게 하는 걸까 ?

결론
베이스 이미지에서 다른 종속성이나 새로운 커맨드를 추가할 때는 임시 컨테이너를 만든 후 그 컨테이너를 토대로 새로운 이미지를 만든다!!! 그리고 그 임시 컨테이너는 지워준다.

도커로 어플을 실행하기 위해서는...

현재까지는 Dockerfile을 그냥 한 가지만 만들었지만 실제로는 Dockerfile을 개발단계를 위한 것과 실제 배포 후를 위한 것을 따로 작성하는 게 좋다.
그러므로 개발단계를 위해서 Dockefile이 아닌 Dockerfile.dev 라는 파일을 작성해보겠다.(Dockerfile 하나로 작성)

왜 저번에는 alpine 베이스 이미지를 썻는데 이번엔 node 이미지를 쓰는지 ?
-먼저 한번 베이스 이미지를 alpine으로 해서 build를 해보겠다.
⚠️ npm not found 에러 발생
➡️ 그 이유로 alpine 이미지는 가장 최소한의 경량화된 파일들이 들어있기에 npm을 위한 파일이 들어있지 않아서 RUN 부분에 npm install을 할수가 없다.
알파인 이미지의 사이즈는 5MB정도로 매우 작다.
그렇기에 npm이 들어있는 베이스 이미지를 찾아야 하는데 그것들중 하나가 node 이미지이다.

npm install은 무엇인가 ?

개발 환경에서의 도커 파일 작성은 현재까지 도커 파일 작성했던 것과 똑같이 하면 된다.
이렇게 Dockerfile.dev를 작성한 후, 이 도커 파일로 이미지를 생성하면 된다.
그러므로 docker build ./ 으로 이미지 생성해보겠다.




이미지가 생성되었다. -> 이미지를 이용해서 컨테이너 실행-> 리액트 실행됨


⚠️unable to evaluate symlink ...이러한 에러가 보인다.
그 이유는 원래는 이미지를 빌드할 때 해당 디렉토리만 정해주면 dockerfile을 자동으로 찾아서 빌드하는데 현재는 dockerfile이 없고 dockerfile.dev밖에 없다.
그러기에 자동으로 올바른 도커 파일을 찾지 못하여 이런 에러가 발생한다.
해결책은 임의로 build 할 때 어떠한 파일을 참조할지 알려준다.
임의로 알려주는 방법은 빌드를 할 때 그냥 docker build .으로 하는 게 아니라 이 아래처럼 해줘야 한다.
그래서 이런 식으로 -f 옵션을 이용하여서 다시 해보면 개발단계에서 리액트를 실행하게 해 줄 이미지 빌드가 가능해졌다.
✅Tip
현재 로컬 머신에 node_modules 폴더가 있다.
이곳에는 리액트 앱을 실행할 때 필요한 모듈들이 들어있지만
이미지를 빌드할 때 이미 npm install로 모든 모듈들을 도커 이미지에 다운로드하기 때문에 굳이 로컬 머신에 node_modules을 필요로 하지 않는다. 그러기에 node_modules을 지워주면 좋다.
현재까지 컨테이너를 실행하기 위해 사용한 명령어

앞으로 컨테이너를 실행하기 위해 사용 할 명령어 
새롭게 추가된 부분은 무엇을 위한 부분인가 ?
우리가 이미지를 만들 때 로컬에 있던 파일(package.json)등을
컨테이너에 복사해줘야 했었다.
그것과 비슷하게 네트워크도 로컬 네트워크에 있던 것을 컨테이너
내부에 있는 네트워크에 연결을 시켜주어야 한다.
포트 3000번으로 접근하면 컨테이너 안의 3000번으로 들어갈 수 있도록
이 명령어를 이용해서 다시 실행 
3000번 포트를 이용해서 애플리케이션에 접속하기



리액트가 잘 실행된다.
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-22-04
앞서 리액트 앱을 실행할때 너무나 긴 명령어를 치는게 많이 불편했었다. 그러한 불편을 해소하기 위해서 도커 Compose를 이용해서 방금 실행한 리액트 앱을 다시 실행해보겠다.

1. 먼저 docker-compose.yml 파일 생성
2. docker-compose.yml 파일 작성하기


3. docker-compose를 이용한 어플리케이션 실행
