Docker 튜토리얼

·2022년 3월 22일
0

TIL

목록 보기
4/36
post-thumbnail

도커란 무엇일까, 사실 들어는 봤는데 뭔지는 잘 몰랐다.
그래서 수업을 들을면서 생각한 것을 적어보려고 한다.


인생을 살다보면 컴퓨터 한대로는 도저히 해결할 수 없는 문제에 직면한다.
컴퓨터가 저렴한 것도 아니기 때문에 다량을 구매할 수도 없기에 사람은 또 고민을 해서 해답을 찾아낸다.
사람들이 생각한 것은 컴퓨터 속에 컴퓨터를 넣으면 되지 않을까? 라는 생각으로 가상 머신(컴퓨터)가 생겨났다.

그러나 가상머신들은 일반적으로 무거웠고, OS에 따라서는 호환성의 문제도 존재했다.
아래 두개의 이야기를 한번 읽어보자.

내 경험

대표적으로 유명한 것은 VMware인데 써본 사람들이 얼마나 있을지는 모르겠지만,
과거에 게임을 한창 할 때 계정을 여러개를 돌려야할 필요가 있어서 4개~6개정도 키고 사용해본 적이 있었는데,
정말 조작감도 너무 안좋았고 내 컴퓨터의 일부를 가져다 쓰는 것이기에 처리도 느리고 내 컴퓨터 자체도 느려지는 상황이 발생했다.
나는 게임만 키고 싶었지만, 게임 뿐 만 아니라 이것저것들에서 CPU와 RAM을 할당 받고 있었기에 벌어진 일이였다.

강의 때 이야기

강의 때 들은 이야기로는 프로그래밍을 하는 회사에 새로운 직원이 입사를 했는데
깔아야하는 다양한 프로그램과 사용하는 프로그램의 버전 그리고 OS가 다른 것이 큰 문제가 되어 이런저런 일이 발생했다고 한다.


위의 다양한 불편함을 해결하기 위해 생겨난 것이 Docker이며 조금 쉽게 생각하면 클라우드 서비스라고 생각해도 될 것 같다.

Docker는 리눅스를 기반으로 만들어져있으며, 순수하게 필요한 프로그램만 가동시킬 수 있도록 시스템이 구현되어있다.
만약에 나는 게임만 돌리고 싶으면 다른 프로세스는 다 잘라버리고 게임만을 돌릴 수 있기에 내 평소 컴퓨터보다 조금 더 향상된 느낌이랄까?
물론 게임은 안돌아간다. 안...돌아갈껄?

그 덕분에 엄청나게 가볍고, 적은 용량을 차지하며 한개의 컴퓨터로 다양한 작업을 해야할 경우 절실히 필요한 아이템이 되어버렸다.

원래는 프로그래밍을 하기 위해서는 다양한 프로그램들이 필요해서 컴퓨터를 백업 없이 포맷을 할 경우에는 시간이 상당히 오래걸렸는데
도커의 라이브러리 덕분에 이런저런 프로그램을 다운받지 않아도, 누군가 올려놓은 이미지를 통째로 다운 받을 수 있다.
그렇기에 자신이 만든 다양한 프로젝트라던가, 누군가 새로운 신입이 왔을 경우 그것을 업로드하여 다운받으면 순식간에 세팅을 끝낼 수 있다.

또, 필요한 최소한의 리소스만을 활용하기 때문에 여러개의 도커를 켜서 다양하게 할당을 할 수도 있다.
하나는 웹서버 다른 하나는 데이터베이스서버 등등등 매우 가볍게 사용할 수 있다.


그렇다면 위에서 말하는 이미지란 무엇일까?

과거에 윈도우를 좀 깔아봤다는 사람이라면,
윈도우를 CD에 구울 경우나 CD게임을 샀을 경우 우리는 ISO(이미지 확장자)파일을 볼 수 있었는데
그것과 같은 이미지파일과 같다고 생각하면 된다.
일반적으로는 실행이 되지 않았기에 데몬과 같은 프로그램을 사용했던 것이 기억난다.

하지만 도커는 그것을 실행할 수 있는 구조가 형성이 되어있기에 유저들은 조금 더 손쉽게 사용할 수 있고
더 큰 상위 개념으로 컨테이너라는 것이 존재하는데 상당히 복잡해서 자세한 설명은 다음에 찾아봐야할 것 같다.


대충 사용방법 & 주요 명령어

FROM 이름:버전 // 이미지 다운로드


WORKDIR /이동할 좌표/ 커서 이동


COPY ./index.js /myfolder/
최상위 디렉토리 /에서 myfolder/를 생성해서 그 안에
현재 폴더에 있는 index.js를 복사
COPY . /myfolder/
현재 들어가있는 폴더의 모든 파일 복사


RUN 프로그램 실행할 프로그램 반복
CMD 프로그램 실행할 프로그램 1회성

RUN yarn install
외부에서 node_mudules를 깔아서 넣지 않고
package.json에 버전을 다 명시해놓은 상태로 Docker에 넣어서 내부에서 yarn install
이렇게 사용하면 접근가능한 사람들은 모두 같은 버전으로 사용할 수 있다.


복사할 경우 특정 파일 무시하기
.dockerignore 파일을 생성해서 무시할 파일명 입력하기


도커 빌드 명령
터미널에서 docker build . (.은 현재 위치를 뜻한다)
깔려는 위치에는 Dockerfile 파일이 존재해야함
vmware에 컴 하나 새로 깔았다고 생각하면 편함


현재 켜져있는 도커 프로세스 확인 명령 docker ps

지금까지 켜봤던 컨테이너 확인
docker ps -a
한번이라도 켜봤던 컨테이너 전부 삭제
docker rm docker ps -a -q

켜봤던 컨테이너 이름 지우기
dokcer rm "컨테이너 ID"

이미지 실행하기
docker run "실행하길 원하는 image의 ID값"

이미지 확인하기
docker images

이미지 삭제하기
docker rmi "이미지ID"
이미지 전부 삭제
docker rmi docker images -q

이미지 종료
docker stop "컨테이너 아이디값"
현재 실행중인 모든 컨테이너 종료 백틱 사용해야함
docker stop docker ps -q

도커 초기화
docker system prune -a


실행중인 컨테이너에 접속, 추가 및 수정 선언 명령

docker exec -it "컨테이너 아이디값" /bin/bash (터미널 실행)

터미널 명령, 맥과 동일함
ls : 현재 폴더 속 확인
pwd : 현재 경로
cd ../ :상위 폴더


웹서버를 켜놨음에도 불구하고 http://localhost:3000/ 이 실행되지 않는 이유.

localhost:3000는 현재 컴퓨터에서 실행 중인 것을 찾아오는데

docker 내부에서 3000번으로 실행 중이기 때문에 내 컴퓨터에서는 찾지 못한다.

그래서 docker쪽에서 호스트를 열어주면
내 컴퓨터가 호스트를 찾다가 해당하는 docker의 포트에 접속된다.

이것을 포트포워딩이라고 부른다.

그리고 이러한 과정 속에서
컴퓨터포트와 docker포트 열어놓게 되면, 포트번호가 다르더라도 다른 곳으로 연결을 시켜줄 수 있다.

포트포워딩 적용 방법
docker run -p 내 컴퓨터 포트:도커 포트 아이디값

포트가 2000->3001로 이동 된 것을 볼 수 있다.


두번째 빌드부터 속도가 빠른 이유

처음 빌드를 올리면 속도가 상당히 느린데
첫 빌드의 진행 중 데이터들을 임시저장(캐시화)이 되어있기에 추가로 빌드를 할 경우에 빠르게 빌드가 올라간다.
하지만 초기화를 할 경우에는 임시저장된 것들 또한 사라진다는 것을 유념해야한다.

임시 저장된 것들이 부셔지는 경우

FROM node:14
WORKDIR /myfolder
COPY . /myfolder/
RUN yarn install
CMD node index.js

docker 또한 javascript처럼 위에서 아래로 내려오는 캐스캐이딩 언어이기 때문에
위에서부터 아래로 코드를 불러오게 된다.

그렇기에 만약 이렇게 위의 형식처럼 빌드를 할 경우에
파일의 일부가 변경되어있다면 그 아래의 파일들이 전부 캐시화되어있던 것들이 깨져서
새로 다운을 받아야만 하는데
모듈이 변한 것이 없다면 새로 다운받아야할 이유가 없기 때문에
파일을 복사하는 것을 하단으로 내리는 것이 빌드 속도에서 이득을 볼 수 있다.

yarn install으로 package.json의 버전을 보고 모듈을 다운받지만
그것은 우리가 사용하고자 하는 버전만 명시가 되어있다.

그러나 라이브러리들은 다른 라이브러리들을 복합적으로 조합되서 만든 것 이기 때문에
그런 버전들의 옵션이 명시되어있는 yarn.lock 파일 또한 같이 가져와야만 한다.

yarn.lock은 깃헙 서버에 올라가있는 웹에 접속하여 다운로드를 받는 방식으로 진행된다.

그래서 최종 코드는 이런식이다

FROM node:14
WORKDIR /myfolder
COPY ./pacgake.json /myfolder/
COPY ./yarn.lock /myfolder/
RUN yarn install
COPY . /myfolder/
CMD node index.js

docker.compose

도커를 여러가지 프로그램을 실행해서 사용할 경우
서로 다른 컴퓨터로 취급하기 때문에 데이터의 이동이 번거로워졌다.

그래서 여러가지의 도커를 한개로 묶어서 활용하는 docker.composw라는 개념이 생겨났다.

설정파일은 .yaml이라는 확장자를 사용하며

services: 속에 필요한 서비스를 입력하면 되는데 들여쓰기가 상당히 중요하다.

들여쓰기를 잘못하면 부모와 자식의 관계가 되어있기에 사용하는 것들을 동시에 실행을 할 경우에는 유의해야한다.

빌드 : docker-compose build
실행 : docker-compose up

docker.composw를 사용하면 같은 부모를 가지고 있는 자식들의 관계가 형성이 되어있기 때문에
api가 존재하는 api docker와 db가 존재하는 db docker 서로의 포트포워딩의 문제가 없어진다.


또, docker.compose를 할 경우에는 이름만으로 서로를 커넥팅하는 name Resolution 라는 것을 사용할 수 있게 되는데
js 파일에 몽고DB의 ODM인 몽구스를 사용하여 아래처럼 적으면
mongoose.connect("mongodb://아이피주소:포트번호/데이터베이스이름")
.yaml 의 설정파일에 포트번호를 명시하지 않더라도 알아서 연결해준다.

하지만 도커가 아닌 내 본 컴퓨터에서 접속을 하기 위해서는 포트포워딩을 꼭 선언해줘야한다.

그리고 .yaml의 파일에 -가 붙는 경우가 있는데, 이 경우에는 배열이라서 다양한 값을 넣어야할 경우에 사용된다. 있어야 하는 것인데 없으면 작동이 안된다


본 컴퓨터의 파일을 수정하더라도 도커 내부의 파일은 달라지지 않기 때문에
계속 끄고 새로 빌드하고를 반복해야했다.

본 파일에서는 이것을 nodemon, pm2같은 응용프로그램으로 사용을 했는데
pm2는 잘 모르겠지만 nodemon의 경우에는 도커 내부에서도 사용하는 방법이 있어서 서술한다.

nodemon의 경우 일반적으로 사용을 하려면 패키지파일에 스크립트를 열어서 명령어를 지정하고 실행하는 파일 명을 적어넣었는데

도커의 경우에는 외부의 파일이 수정되더라도 본인 것이 수정이 되는 것이기 아니기에 링크 작업이 필요하다.
그러한 작업을 할 때 사용하는 명령어는 volumes라는 것이고

포트포워딩과 같은 형식으로 내가 외부에서 실행시키는 파일명 : 도커 내부에서 실행시키는 파일명의 구조로 사용할 수 있다.

그래서 최종적으로 현재 작업중인 나의 도커yaml파일은 이러하다.

p.s 뭔가 안되면 도커 초기화했다가 새로 빌드하는게 처리하는게 제일 빨랐다
망할것

profile
물류 서비스 Backend Software Developer

0개의 댓글