-
Docker 실습 - 가장 쉽게 배우는 도커(유튜브) 예제Docker 2020. 11. 24. 13:18
www.youtube.com/watch?v=hWPv9LMlme8
* 참고 사이트
사전 준비
1. docker 설치
2. git 설치
3. vsCode 설치
1. 실습 폴더 생성
2. vsCode로 실습 폴더를 열고 terminal로 git clone 수행.
git clone https://gitlab.com/yalco/practice-docker.git
위의 사진과 같이 정상적으로 clone 됨을 확인.
💻 이 프로젝트는 node.js와 http-server를 이용하여 front - back - db로 연결하여 웹 브라우저에 화면을 띄워 구동하는 구조
필자의 컴퓨터에 node.js가 설치되어 있지 않다고 가정하고 docker를 이용하여 사용자가 구현했던 개발환경과 동일한 환경에서
이 프로젝트를 수행해보기로 함
- terminal에서 밑의 명령어 수행
jaeho@jaehoiui-MacBookPro dockerTest % docker run -it node
아래와 같은 에러 코드가 나타나는데
Unable to find image 'node:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/library/node/manifests/latest:unauthorized:incorrect username or password.
See 'docker run --help'.에러 코드를 자세히 읽어보면 username과 password가 인증되지 않았다는 것을 확인할 수 있음
- 터미널에 밑의 명령어를 입력후 username과 password 입력 후
docker login
run 명령어 수행
docker run -it node
입력 콘솔이 바로 나타나는 것을 확인할 수 있음
✅ 여기서 이 node.js환경은 어디서 나타난 것일까??
확인을 위해
이 사이트는 우리가 무엇인가를 개발할 때 필요한 거의 모든 환경들을 "이미지" 란 형태로 찾을 수 있다.
node도 이처럼 공식 이미지가 올라와 있는 것을 확인할 수 있다.
도커의 이미지라는 것은 리눅스 컴퓨터의 특정 상태를 "캡쳐" 해서 박제해 놓은 것을 말한다.
node 이미지는 리눅스에 node.js가 설치된 상태를 그대로 급속 냉동해다가 클라우드에 올려놓은 것!
오잉? 그럼 이게 어떻게 내 컴퓨터에 설치 되었을까?
도커는 일단 내 컴퓨터에서 그 이미지를 찾아본 뒤, 존재하지 않는다면 docker hub 로부터 해당 이름으로 등록된 이미지를 다운받게 된다.
run 명령어는 그 이미지를 다운받은 후 해동해서 컨테이너로 만드는 명령어!
-> 이미지를 한번 다운받으면 컨테이너를 몇개든 만들어 낼 수 있다.
* 이미지는 컨테이너를 찍어내는 틀 or 무한생산 가능한 컨테이너 조립 키트!
run 명령어와 함께 사용한 -it는 이 컨테이너를 연다음 그 환경안에서 CLI를 사용하겠다 ! 라는 의미
그리고 이 이미지는 컨테이너가 만들어져서 설치되면 바로 node 명령어가 실행되도록 설계되어 있다.
그리서 컨테이너가 만들어 지자마자 입력창이 뜨는 것!
자! 그럼 상태를 한번 확인해보자!
터미널을 하나 새로 열고
docker images
node라는 이름의 image가 다운받아진 것을 확인할 수 있다!
따라서
docker run -it node
명령어를 수행하면 이미지를 새로 다운받을 필요없이 바로 콘솔이 실행된다.
이번에는 컨테이너를 살펴보자!
docker ps
명령어를 수행하면
이처럼 이름이 임의로 지어진 컨테이너를 확인할 수 있다.
그렇다면 뒷문으로 들어가서 이 컨테이너 안을 살펴보자!
docker exec -it peaceful_blackwell bash
-it 뒤에는 컨테이너 names를 입력해주면 된다.
이 컨테이너 내에서 bash shell을 실행한다는 의미!
* 윈도우에서 파워 쉘로 CLI 명령어를 입력할 수 있듯, 맥이나 리눅스, 유닉스에서는 배쉬 쉘 등이 있다고 생각하면 된다.!
명령어를 입력하면 조금 색다른 명령어 콘솔이 나타난다.
이 컨테이너 내부를 통해 가상의 리눅스 환경으로 들어간 것!
ls
ls 명령어를 통해 리눅스 환경의 기본 디렉터리들을 확인 할 수 있다.
--> 컨테이너마다 각각 이 파일시스템과 네트워크가 있다는것!!
그렇다고 리눅스 전체가 다 들어가 있다는 것은 아니다!
이 리눅스 환경은 도커 데스크탑 프로그램으로 구현되고 있는 것!
우리들이 어떤 OS에서 도커를 돌리던, 도커의 컨테이너들은 리눅스 가상환경의 형태로
돌아간다는 것을 기억하면 된다.
다시 이전의 터미널로 돌아와서 Control + C로 node의 컨테이너를 종료해보자!
컨테이너 안의 node.js와 회의를 끝냈다는 의미!
docker ps
명령어를 통해 실행중인 컨테이너를 확인해보면 이전에 있던 컨테이너가 보이지 않는 것을 확인할 수 있음!
-> 그렇다면 이 컨테이너가 완전히 철거되었다는 의미일까??
답은 NO!!
docker ps 명령어는 현재 작업중인 컨테이너만 표시되게 하는 명령어!
docker ps -a
명령어를 통해 모든 컨테이너를 확인 할 수 있음!
* 현재 중지되어 있는, 작업중이 아닌 컨테이너도 확인가능
다운받은 node의 컨테이너와 이미지를 삭제하고 이제 실습을 다시 시작해보자!
방금처럼 컨테이너를 펼친다음 그 안의 이미지에게 CLI로 할 일을 직접 명령하는 것으로는 서비스를 돌리기 위한 복잡한 작업들을
제대로 할 수 없다. 그래서 보다 섬세한 활용을 위해 Dockerfile이 활용된다.!!
clone한 프로젝트안을 보면 frontend, backend, database폴더에 모두 Dockerfile이라는 파일이 있는 것을 확인할 수 있다.
✅ Dockerfile은 나만의 이미지를 만들기 위한 설계도
아니? node 이미지를 받았는데 내걸 왜 또 만들어??
컴퓨터에서 http-server란 프로그램을 돌리려면 node.js만 설치되어 있어서는 안되죠?
npm 등으로 http-server가 전역으로 설치되어 있어야 합니다
다운받은 node 이미지는 아직 http-server가 설치되지 않은 상태이기 때문에 이를 컨테이너로 실행할 때마다 매 번 http-server를
설치해줘야 하는 번거로움이 있다.~~
만약 이런 모듈들이 더 필요한 프로젝트라면 이러한 모듈들을 서비스를 돌릴 때마다 일일이 다운받아 줘야한다.. ㅜㅜ
그래서! node.js에다 http-server까지 설치되어있는 상태가 이미지로 있으면 이러한 과정을 반복할 필요가? 없다!
[frontend/Dockerfile]
->
FROM
우리가 만들 이미지는 node:12.18.4 버전의 이미지에 덧붙여서 ! 즉, node의 공식 이미지를 개조, 튜닝해서 만들겠다~ 라는 의미
RUN
이미지를 생성하는 과정에서 실행할 명령어
-> node.js가 설치된 이미지니까 npm 명령어가 수행가능하겠죠 ? 이 단계에서 http-server를 설치해준다.
WORKDIR
WORKDIR 명령어는 이 안에서 명령어를 실행할 위치를 설정한다.
CMD 에서 문자열의 배열로 명시한 명령어가 WORKDIR 로 지정한 /home/node/app이란 디렉토리에서 수행되는 것!!
* RUN 명령어와 CMD 명령어의 차이!!
- RUN : 이미지를 생성하는 과정에서 수행되는 것
즉, 이미지에서 컨테이너를 실행하는 시점에서는 이미 http-server가 설치되어 있도록 하는 것~
- CMD : 이미지로부터 컨테이너가 만들어져 가동될 때 수행되는 명령어, 기본적으로 바로 수행되는 명령어~
CLI에서 frontend 폴더로 들어온다음
-t 뒤에 [원하는 이미지명] [Dockerfile로의 상대경로 (파일명이 Dockerfile이면 파일명을 따로 입력해줄 필요 x)]
docker build -t frontend-img .
실행을 해주면 이처럼 node 컨테이너를 다운받은 다음 지정한 명령어들을 실행하는 것을 볼 수 있다.(빨간색 박스)
그리고 이미지 목록을 확인해보면
docker images
node이미지가 생성되었고 이를 기반으로 frontend-img 이미지가 생성된 것을 확인할 수 있다.
frontend-img에는 지정했던 명령어들이 이미 실행된 결과가 이미지로 담겨있기 때문에 이미 http-server가 설치된 이미지인 것을
확인할 수 있다.
그렇다면 우리가 커스텀한 이 이미지를 run 해보자!
이번 run 명령어는 아까보다 옵션이 많이 들어가는데
docker run --name [생성할 컨테이너 명] -v [이 폴더의 내용을 저장할 폴더] -p [내선 포트:컨테이너 포트] [실행할 이미지]
docker run --name frontend-con -v $(pwd):/home/node/app -p 8080:8080 frontend-img* -v : volume 의 약자인데 "컨테이너와 특정 폴더를 공유하는 것"
$(pwd):/home/node/app -> pwd는 현재폴더를 의미하는데 -> 현재폴더의 내용을 /home/node/app 폴더에 넣겠다~ 이런 의미
-p : port 옵션 -> 집의 내선번호를 컨테이너의 것과 연결하는 것
자 실행을 해보면!!
8080 으로 서버가 열렸다는 표시가 나오고
실제로 브라우저에서 열어보면 backend와 database가 연동되지 않았기 때문에 위와 같은 메세지가 출력되는 것을 확인할 수 있다.
그럼!! 이제 backend와 database를 연동해서 해보자! 그러기 위해선 실행한 컨테이너와 이미지를 모두 삭제하고
database 폴더로가서 Dockerfile 을 이미지로 만들어보자!
FROM
mysql 5.7버전을 다운받아 개조할 거다!
ENV 명령어로 생성될 컨테이너 안의 환경변수를 미리 지정한다!
-> mysql에서 어떤 사용자 아이디와 비밀번호 등을 사용할지 미리 알려주는 것 -> 실제로는 이런 정보들을 여기 적어두는건 매우 위험!!
COPY
이 script안에 있는 이 파일들을 이미지 내부의 COPY 옆에 적힌 폴더로 복사를 한다!
이 mysql 이미지는 컨테이너로 실행이 될 때
이 폴더안에 적힌 쿼리 명령어들을 실행한다.
COPY는 RUN처럼 이미지를 생성하는 과정에서 미리 해당 이미지안의 특정 폴더에 특정 파일을 미리 넣어두는 것!
마찬가지로 database 폴더로 이동한다음!
이미지부터 생성해보겠다!!
docker build -t database-img .
이미지를 생성한 후에 이 이미지를 가지고 run을 수행하자
docker run --name database-con -it -p 3306:3306 database-img
* 이번 컨테이너는 컨테이너 명과 포트만 지정해주면 된다!
실행하면 로그들이 막 뜨고 3306 포트로 실행이 되었다는 것을 확인할 수 있다.
근데 이렇게 실행을 하면 터미널에서 다른 명령어를 수행해줄수가 없다 그래서
docker run --name database-con -it -p 3306:3306 -d database-img
run할때 -d옵션을 주면 안보이는데 저~기 뒤에가서 혼자 실행하고 있어~ 라는 의미의 옵션을 준다.
이렇게 수행해주면 생성된 컨테이너의 id만 표시가되고 터미널은 이어서 계속 사용할 수 있다
또한 docker ps 로 확인해주면 컨테이너가 잘 작동되고 있음을 확인할 수 있다.
그리고 일을 어떻게하고 있는지 컨테이너의 로그를 살펴보고 싶으면
docker logs -f [컨테이너명]
docker logs -f database-con이렇게 실시간으로 로그를 확인해볼수 있고 ctrl +c로 빠져나올 수 있다.
backend도 비슷한 구조이기 때문에 생략하고
frontend, database, backend라는 서비스 a를 구성하는 세가지 요소가 각각의 폴더안에 Dockerfile라는 미시적 설계도로 도커에서
어떻게 실행될지 설정이 되어 있는거!!
그런데!!!!
이렇게 서비스를 실행할때 매번 이러한 요소들을 이미지로 하나하나 다운받고 적절한 명령어로 컨테이너를 실행하는 건 여전히 번거롭다...
게다가 각각의 네트워크가 분리되어 있기 때문에 backend와 database는 데이터를 주고받을 수가 없다...
이 요소들을 연결해서 서비스를 간편하게 연결할 수는 없을까!?!?!?
이를 위해 거시적 설계도인 docker-compose.yml가 사용이된다.!!
이를 위해 모든 컨테이너와 모든 이미지를 삭제하자!!
[docker-compose.yml]
docs.docker.com/compose/compose-file/compose-versioning/
이 페이지에서 도커 버전마다 적합한 컴포즈의 버전을 확인할 수 있다.
서비스 a를 이루는 세가지 요소 frontend, backend, database 폴더들은 docker-compose에 내부항목으로 들어가 있다!!
그럼
docker-compose up
명령어를 실행하면
브라우저에 localhost:8080을 입력하면 잘 작동하는 것을 확인할 수 있다.
참고
도커 관련 명령어 정리!!