Docker에 대해 알아보쟈




Docker



도커란 무엇인가?

부팅 등 운영체제의 핵심 기능(커널)을 공유하는 가상머신.

간단히 말하면 그냥 가상 컴퓨터라고 생각하면 됨.

도커가 왜 필요한가?

개발자들과 협업을 하다보면 환경설정하는 부분에서 꽤 많은 시간이 소요된다.

그리고 개개인이 가지고 있는 컴퓨터의 OS도 모두 다르다. (운영체제에 따라 환경도 달라짐)

그리고 아무리 컴퓨터 설정을 제대로 해준다고 하더라도 모든 컴퓨터의 디폴트 상태가 각기 전부 다 다르기 때문에

바로바로 챡챡챡 진행되는경우가 (있다면 베리 럭키) 잘 없어서 동일한 환경설정을 해주는게 사실 굉장히 귀찮기도 하고 시간도 오래걸린다.

그래서 OS를 통일하고(동일한 환경세팅) 버전도 맞춰주기 위해서 동일한 OS를 사용하도록 세팅해준다.

윈도우안에 리눅스VM 맥 안에 리눅스 VM 리눅으안에 리눅스VM를 띄운다. (버전도 동일하게)

도커를 사용하게 되면 OS전체를 새로 설치하지 않아도 된다.

(윈도우에서 리눅스를 사용하게끔 하게는 WSL2(=Window-Subsystem-for Linux) 라는게 필요한다. )

도커파일(Dockerfile)이라는 것이 공유가 되어있다면 첫 사람만 설치하게되면 다른 사람들은 그냥 설치가 된다

(느므 편함. 새로운 사람 들어와도 도커파일만 있으면 바로 설치됨. )

기존의 VMWare는 굉장히 무거웠는데 도커는 가볍기까지 함.

  1. 개발/배포환경 통일 (컴퓨터1대를 구매해서 yarn start:dev를 하루종일 띄워놓기)
  2. 프로그램 미리 설치
  3. 가벼운 가상컴퓨터


//index.js

console.log('이 파일은 도커 안에서 실행됩니다');

//도커의 특징 : Dockerfile의 마지막 명령문인 CMD node index.js 명령어가 끝나고나면 할일을 다 해서 컴퓨터가 꺼져버리게 됨. 종료가 되면 다시 접속할수가 없음. 그래서 종료가 되지 않도록 무한 루프를 돌려야함.(=컴퓨터 종료안됨)
while (true) {}


//Dockerfile


# 컴퓨터 만드는 설명서

# 1.운영체제 설치(노드14버전과 npm과 yarn이 모두 설치되어있는 리눅스)
FROM node:14

# 2. 내 컴퓨터에 있는 폴더나 파일을 도커 컴퓨터 안으로 복사하기
RUN mkdir qqq
COPY ./index.js /index.js


# 이미를 만들때 포함 되는지 안되는지
# 미리실행시켜놓은 명령어를 저장시켜놓을 것이냐
#설치 명령어(두번 이상 실행가능 )
# RUN node index.js 

########↑이미지파일로 저장(명령어는 docker build)##############
########↓ 실행(명령어는 docker run)##############


# 3. 도커안에서 index.js 실행시키기
# 실행명령어(한번만 실행가능 )
CMD node index.js


도커 빌드하기

docker build .

실행되고 있는 도커이미지 목록 보여주기

docker images

IMAGE ID에 해당하는 도커를 실행하라

docker run IMAGE ID(0084591ff39w같은거..)

실행되고 나면 새로운 터미널을 켜준다.

실행되는 터미널에서는 명령어를 칠 수 없기 때문!

docker ps

도커 프로그램이 몇개가 실행중인가? 확인하는 명령어

그러면 실행되고 있는 도커 컴퓨터를 확인할 수 있다(앞으로는 도커 컴퓨터 = 도커 컨테이너라고 부름)

docker exec -it CONTAINER ID /bin/bashe

'’도커 실행해주고 접속(t)해서 수정(i)할 수 있게 해줘’‘라는 명령어

/bin : 실행파일

bash : 커서 깜빡거릴수 있는 실행파일 (cf. 커서깜빡거리는걸 bashshell 이라고 함)

이렇게 명령어를 실행하면 터미널에서

$root@CONTAINER ID:/# 

이렇게 나온다.

내가 사용하고 있는 맥의 터미널의 cmd와는 다름

바로 도커 컨테이너에 들어온것!!!!

#뒤에는 명령어를 칠 수 있다.

예를들어

$root@CONTAINER ID:/# ls

이렇게 치게되면 도커 컨테이너 안의 파일구조를 확인할 수 있다.

이 컨테이너에서 파일을 만들든 폴더를 만들든 그거는 내 로컬 컴퓨터와는 아무런 상관이 없다.

완전 다른 컴퓨터에 생성된것



만약 이 도커 컨테이너에서 빠져나오고 싶으면

$root@CONTAINER ID:/# exit


도커를 종료하는건 명령어가 따로 필요하다. 컨테이너를 스탑해주어야 함

docker stop CONTAINER ID




도커 포트 포워딩

예를들어,

포스트맨에서 http://localhost:3000/boards 로 요청을 하게 되면,

3000번 포트로 실행중인 프로그램을 찾게 되고,

내 컴퓨터 안에 3000으로 실행되는 포트를 찾아 서로 연결한다. (그게 express로 통신하는거)

그렇게 서로 통신하는데, 이번에는 express가 내 컴퓨터 안에 있는게 아니라 도커 안에서 express가 실행되고 있으니까

포스트맨에서 아무리 찾아도 도커에 가려져 있어서 찾지를 못한다는거다.

그래서 도커에서 찾으려면 도커 안의 express와 연결을 시켜주어야 하는데, 이게 바로 도커 포트 포워딩이다.

도커 포트 포워딩은 ‘내가 받은 포트를 안의 포트랑 연결해줄게’ 라는 뜻이다.


도커에서 포트를 변경해줄 수 있는데

docker run -p 2000:3000 CONTAINER ID

-p : 포트

2000:3000으로 제대로 설정됐는지 확인하는 법

$docker ps

라고 명령어를 내리면 0.0.0.0:2000->3000/tcp 라고 새롭게 PORTS가 뜬다.

이 말은 2000번 포트에 접속한 그 누구든지 3000번 포트로 포워딩을 해주겠다

새롭게 뜨면 제대로 된것


0.0.0.0 : 누구든지 접속 가능

127.0.0.1 : 나 자신. 로컬호스트


만약에 포트포워딩을 시키고 싶으면 터미널에서 포트번호를 바꿔주는 것도 중요하지만,

도커컨테이너 안의 index.js의 app.listen(포트번호, () => {console.log('백엔드 api서버 작동!')}) 의 포트번호를 바꿔줘야한다.

로컬의 index.js를 수정했는데 nodemon refresh가 왜 안되냐고 묻는다면,

도커안의 파일을 수정한게 아니라서 그렇다고 답할 수 있다.

로컬의 index.js를 암만 바꿔본들 소용없음

왜냐면 처음에 복사해주고나서는 이제 아예 다른 컴퓨터 안에있는 독립적인 파일이니까…

그래서 방법은 여러가지가 있지만 vim을 사용해서 파일 내용자체를 터미널에서 수정해주는 방법이 있고,

(도커 컨테이너 안에서 파일을 열어보는 법. index.js 파일을 열어보고 싶을때는 cat 을 쓴다)

$cat index.js


아니면 아예 빌드를 처음부터 다시 해서 로컬에서 수정한 파일을 다시 도커 컨테이너에 복사하는 방법이 있다.

아직은 vim을 배우지 않았으므로 빌드를 다시 해보기로 한다.

$docker build .
$docker images
$docker run -p 2500:4000 IMAGE ID

이렇게 다시 빌드를 해주면 postman에서 2500으로 접속해야 api에 접근가능하다



물론 매번 이렇게 빌드를 할 수 없기 때문에 볼륨즈라는것을 쓸거지만,

만약 빌드를 매번해야한다고 가정한다면, 속도를 빠르게 하는 방법은 있다.

$docker build .

빌드를 하면 RUN yarn install 이 매번 실행되기 때문에 느린건데 이게 굳이 매번 해줘야하는지 의문이 생긴다.

빌드를 할때마다 임시저장(CACHE) 에서 매번 저장을 하는데 그렇기 때문에

빌드를 해준다고 하더라도 매번 해주는게 아니라 캐시에서 가지고 오기때문에 훨씬 빠르다.

근데 만약에 package.json이 바뀌었다면?

캐시데이터에서 갖고 오게되면 정말 필요한 lib를 다시 가져와야한다.

근데 도커의 특성상 만약 copy한 내용이 전의 내용과 차이가 있으면 자동으로 그걸 감지해서(git이랑 비슷한듯)

캐시를 깨뜨린다. 그리고 한번 캐시가 깨지면 그 밑에 줄의 캐시를 다 깨뜨려버림.


그러면 카피를 조금 더 효율적으로 해야하기 때문에

COPY ./package.json /myfolder/
COPY ./yarn.lock /myfolder
WORKDIR /myfolder/
RUN yarn install

COPY . /myfolder

이렇게 파일을 바꿔주면 package.json이 바뀌지 않는 이상 위에는 캐시가 깨지지 않으니까 캐시에서 가져오게됨




도커 종료 & 삭제하기


docker stop CONTAINER ID

살아있는 도커를 끄자.

근데 도커를 끈다는게, 도커를 지우는건 아니다. 단지 종료된 것일뿐.

그러니까 목록에 있는 도커를 지워야 한다. 안그럼 수백개가 될지도;;;ㄷㄷㄷㄷ

docker ps

현재 살아있는 도커 컨테이너를 조회한다


docker rm CONTAINER ID

그리고 도커 컨테이너를 삭제한다


docker ps -a

아직 삭제가 되지 않은 도커 컨테이너들을 확인할 수 있다.

근데 너무 많으면…..? 한번에 삭제하는 방법이 있다.


docker ps -a -q

컨테이너 아이디만 뽑아온다. 그걸 몽땅 삭제해주면 됨


docker rm `docker ps -a -q`

docker rm docker ps -a -q 이렇게 작성하면 안됨!!

중간에 백틱으로 묶어줘야함. 그러면 백틱으로 묶인 명령문 먼저 실행하고 그 다음에 rm을 실행한다.


docker ps

그리고나서 다시 확인해보면 다 지워진걸 확인할 수 있다


끝난줄 알았지?

안끝났음. 이미지도 삭제해줘야함



docker images -q

=도커 이미지 아이디만 뽑아서 모두 볼거임


docker rmi `docker images -q`

이렇게 해주어야 이미지까지 모두 삭제됨~~~

실행되고 있는 이미지는 삭제되지 않음!

삭제되지 않는다면 어디선가 사용되고 있다는 소리


아 나는 다 귀찮고 그냥 다 초기화 해버리면 안되나? 라는 생각이 든다면

docker system prune -a

이렇게 물어보면 진짜 진행할거냐고 물어보는데 거기서 y누르면 전체 삭제됨




© 2018. by sora

Powered by sora