오늘은 Docker🐳 를 처음 사용해봤습니다.
서버라는 것은 결국 하나의 컴퓨터이기 때문에 효율적인 사용을 위해 도커를 이용해 새로운 서버 컴퓨터를 설정, 사용할 수 있게 된다는 것을 알 수 있었습니다. 이와 관련되서 프론트엔드와 백엔드의 전체 구조에 대해서 설명 했었습니다. 한번 구조를 직접 그려보면서 스스로에게 설명해보세요!
그리고 도커를 사용하기 위해서 필요한 설정 파일들(Dockerfile, dockerignore)과 명령어(docker build, docker run)들이 있었습니다. 이러한 파일들과 명령어가 하는 역할들을 잘 이해해 주셔야합니다. Dockerfile에 작성한 내용을 가지고, 가상 컴퓨터의 이미지를 만들고(docker build), 이 이미지로 컨테이너를 띄웁니다(docker run). 즉, 가상 컴퓨터를 실행하는 것입니다. 실행한 컴퓨터의 터미널에 직접 접속해볼 수도 있었습니다. 하지만, 다른 포트를 가진 컴퓨터가 밖에서 접속하기 위해서는 포트 포워딩을 해줘야합니다!
내일은 더 나아가서 여러개의 도커 컨테이너를 한번에 다루기 위해 docker-compose를 배우게 됩니다.
데이터베이스의 SQL과 NoSQL도 비교해서 알아보았습니다. SQL을 사용하는 관계형 DB의 큰 특징은 엑셀 표 같은 테이블로 데이터가 저장된다는 것입니다. NoSQL을 사용하는 비관계형 DB에서는 JSON 형식 처럼 생긴 documents에 데이터가 저장됩니다. 우리는 미니 프로젝트를 만들면서 NoSQL을 사용하고, 메인 프로젝트를 만들면서 SQL을 사용해보게 됩니다. 몽고DB는 대표적인 NoSQL 데이터베이스이며 내일 공부하게됩니다. 이제 하드코딩된 가짜 데이터가 아닌, DB에 실제 데이터를 저장하고 이용하는 API를 만들 수 있겠습니다!
DB 명령어
: 데이터를 저장하고 조회하는 명령어
=> SQL-Query옛날에는 명령어를 밑과 같이 입력해줘야했었다!(등록과 조회)
당연히 귀찮을 수 밖에 없는 길이!!!!
그래서 DB명령어를 자동생성해주기로 한다.
그러기위해선 백엔드에서 도구를 설치해줘야 하는데, 그게 바로 ORM과 ODM이다!ORM
: Object Relation Mapping, 객체-관계 매핑의 줄임말이다.
객체라는 개념을 구현한 클래스와 RDB(Relational DataBase)에서 쓰이는 데이터인 테이블 자동으로 매핑(연결)하는 것을 의미한다고 한다!
출처: https://geonlee.tistory.com/207 [빠리의 택시 운전사:티스토리]
ORM은 SQL일 때 사용되고 객체형태로 DB에 저장된다!장점
객체지향적인 코드 : SQL문이 아닌 클래스의 메서드를 통해 테이터 베이스를 조작할 수 있다.
재사용성, 유지보수, 리팩토링이 용이 : 객체로 작성되었기 때문에 재활용이 용이하다.
단점
완벽한 ORM 으로만 서비스를 구현하기가 어렵다 : 사용하기는 편하지만 신중하게 설계해야하고, 프로젝트가 복잡해지거나 커질수록 사용하기가 쉽지않다
ORM의 대표적인 도구
Prisma, typeORM(TS), Sequalize(JS)가 있다!
ODM
: Object Document Mapping, Document Database를 지원하기 위해 데이터를 변환하는 프로그래밍 기법이다.
관계형 데이터베이스 뿐만 아니라 다양한 데이터베이스를 다룬다!
ODM은 NoSQL일 때 사용되고 ORM과 마찬가지로 객체형태로 DB에 저장된다!ODM의 대표적인 도구
Mongoose
💡 그러면 SQL-Query문은 몰라도 되는거야?
결론을 먼저 얘기하자면 NO다!!!!!
ORM과 ODM이 내가 원하는 방향(성능 최적화)으로 변형이 안되거나
직접적으로 DB에서 데이터를 꺼내와야 할 때(Backend 없이 접근할 때)
는 SQL-Query문으로 작성해줘야 하기때문에 알아야한다!!!
위 처럼 운영체제에 따라 우리는 달라지는 환경에 힘들어했다.
그걸 개선하기 위해서 기존에는 가짜 컴퓨터를 만들어서 사용했다.
서로 같은 환경의 가짜 컴퓨터를 만들어서 설치를 하기로 한거다!
하지만 가상머신에도 단점이 있었다.
컴퓨터 안에 컴퓨터가 있다보니 속도가 현저히 떨어졌기 때문이다!
그걸 개선하기 위에 나타난게 바로 Docker다!
도커는 우리가 필요한 개발 환경 요소들이 설치된 모습을 이미지로 저장하고, 그 이미지를 올려두는 클라우드에 깃을 올리는 것처럼 올린다! 그 곳을 도커 허브라고 한다!그럼 내가 필요한 이미지를 npm으로 다운받는 것처럼 다운받아 설정해서 사용하면 된다!!!!
[출처](https://medium.com/@darkrasid/docker%EC%99%80-vm-d95d60e56fdd)
위 그림은 왼쪽이 가상머신, 오른쪽이 도커다.
도커는 os 전체를 새로 설치하지 않고, 불필요하게 추가적으로 운영체제를 설치하지 않아도 되서 훨씬 짧다.
자동적으로 속도도 가상머신보다 훨씬 빨라진다!
또 docker는 Linux 이라 Linux와 Linux 기반인 mac은 별다른 설정이 없어도 되지만, window는 WSL(Window subsystem for Linux)을 같이 설치해줘야 한다.Docker의 장점
가상컴퓨터에 파일을 설치해놓고 저장을 할 수 있다.
그래서 나중에 내가 필요한 파일들이 설치되어있는 컴퓨터를 가져와 사용할 수 있기 때문에, 다시 설치하지 않아도 된다!!!!Dockerfile
: 도커 만드는 설명서(=컴퓨터를 만드는 설명서)라고 한다!
도커는 우리가 필요한 개발 환경 요소들이 설치된 모습을 이미지로 저장한다고 했다.
그 이미지를 만들기 위해선 dockerfile이라는 이름의 파일을 만들고 이미지를 만들기 위한 명령어를 입력해야한다!FROM node:14 COPY ./index.js /myfolder/ WORKDIR /myfolder/ CMD node index.js
FROM 리눅스:최신버전 : 리눅스의 최신 버전이 깔린 컴퓨터를 만들어 준다.
그런데 이러면 따로 node, npm, yarn도 설치해야한다.
그래서 도커허브를 찾아보면 node, npm, yarn이 깔려있는 이미지가 이미 있다!
FROM node:14 을 하면 node, npm, yarn이 모두 설치된 리눅스 컴퓨터가 하나 생기게 된다!COPY ./index.js /myfolder/ : 내 컴퓨터에 있는 index.js 파일 안에 있는 모든 소스 코드를 가상 컴퓨터 myfolder 폴더로 복사해준다.
WORKDIR /myfolder/ : 가상 컴퓨터가 만들어지면 명령어를 실행할 작업 폴더를 지정해준다.
CMD node index.js : 가상컴퓨터에 있는 myfolder 폴더에 있는 index 파일을 실행시켜준다.
💡 명령어 정리
RUN : RUN 뒤에 적인 명령을 이 컴퓨터 안에서 실행시켜줘
mkdir : 폴더 만들기
cd : 폴더 이동
FROM : hub.docker.com에서 운영체제 다운로드 받아오기
brew install nodejs : mac에서 node.js 설치(npm도 자동설치)
apt install nodejs : 우분투에서 node.js 설치
npm install -g yarn : npm가지고 yarn 설치
COPY : 내 컴퓨터에 있는 폴더나 파일을 도커 안으로 복사하기 => COPY 내컴퓨터폴더위치 도커컴퓨터폴더위치
RUN yarn dev : docker 안에서 express 실행시키기
CMD : dockerfile 가장 마지막에 실행시켜줘
docker build
dockerfile을 가지고 이미지를 만들어 줄 때, build 한다고 표현한다.
CMD 전까지 최적화된 압축파일로 이미지를 만들어 달라고 요청하는 거다!
그리고 실행을 해준다(CMD 실행)정리
- docker build : build를 통해 이미지 만들기
- docker image : 생성된 이미지 확인
- docker run 이미지ID : 확인한 이미지 실행
⚠️ 혹시 이런 에러가 나온다면, 설치한 docker 프로그램이 켜져있나 확인해 주세요!
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
💡 명령어 정리
docker ps : 실행되고 있는 docker 프로그램
docker ps -a : 종료된 컨테이너까지 모두 보여주기
container ID : 컴퓨터 아이디
docker exec -it containerID /bin/bash : 컴퓨터에 접속
exec : 명령어를 실행시켜줘
exit : docker 나가기
docker stop containerID : docker 끄기
.dockerignore
: 내 node 버전에 맞는 node_modules 말고, docker로 불러온 node 버전에 맞는 node_modules만 yarn install하기 위해 기존에 있는 node_modules를 실행 안시키려면 .dockerignore 파일에 node_modules를 써준다.
이제 도커에서는 node_modules 폴더를 무시하여, COPY . /myfolder/ 명령어로 모든 소스코드를 복사해 올 시, node_modules 폴더가 복사 되지 않는다.
: 가상 컴퓨터의 포트번호와 내 컴퓨터의 포트 번호로 연결
docker 포트 포워딩 실행
=> docker run -p 3000(docker 포트) : 3000(그 안에 있는 express 포트) 이미지ID
왜 express 포트번호가 변경되면 다시 build를 해줘야하나요?
이미 입력해놓은 코드로 build해서 이미지를 찍어놨기 때문에, 변경해서 실행하려면 다시 build해서 새로 이미지를 저장한다.
=> 그러면 yarn install로 새로하는건데 시간이 오래걸리고 바뀔때마다 build를 해줘야하는 번거로움이 크다소스코드 하나 바뀔때마다 build할 수없어 특정 파일을 지정해서 그 파일은 바뀐걸 바로 반영해줘!빌드하지않아고 괜찮아!!하는게 볼륨즈라고 한다!
도커는 최대한 똑같은 명령을 안받기 위해 캐시라는 곳에다가 임시 저장을 한다!
캐시에 이미 저장되어 있는 명령을 가져와서 쓰겠다고 하는 기준은 변경된 파일이 있는 줄 위에 있는 것들은 캐시에 이미 저장되어 있는 명령을 쓰고 변경된 파일 밑에 있는 것들은 모두 다 새로 빌드한다.
그래서 dockerfile 순서를 변경해줘야한다!FROM node:14 WORKDIR /myfolder/ COPY ./package.json /myfolder/ COPY ./yarn.lock /myfolder/ RUN yarn install # RUN mkdir myfolder => myfolder가 없으면 COPY할 때, 어차피 자동으로 만들어짐 COPY . /myfolder/ # 실행명령들 CMD yarn dev
제일 자주 변경될 것 같은 myfolder를 하단에 만들어 줬다.
이렇게Dockerfile
을 작성하게 되면,package.json
과yarn.lock
파일이 수정되지 않았다면RUN yarn install
까지는 기존 것을 그대로 쓰고, 밑에 실제로 소스코드가 고쳐진 부분만 새로 반영되어 실행된다!