본문 바로가기
공부/Node.js

Docker

by silverage 2023. 8. 19.

이 부분은 진짜 제정신 아닌 상태로 써서 그런지.. 제대로 정리도 안 되어있다..

나중에 다시 공부할 때 여기 꼭 수정하고 해야겠음


  • 수업 필기
    • 1 - 도커 설치
      • 운영체제에 따라 달라지는 환경
        • 맥북에서는 되는데 윈도우에서는 안됨 등등..
        • 방법1: 컴퓨터 안에 또 다른 컴퓨터를 깔아보자! (가상 환경, VMWare)
          • 옛날, 도커가 나오기 전 쓰던 방법
          • 겁나 느림
        • 도커: 부팅 등 운영체제의 핵심 기능(커널)을 공유하는 가상머신
          • 빠르고 가벼운 가상머신
          • OS 전체를 새로 설치하지 않아도 된다.
          • 느리지 않고 가볍게 만들어보자..! 하고 만듦
          • 커널(공통 기능, 핵심 기능 등)을 같이 쓰기로 함 → 가상머신이 빨라지고 가벼워졌다!
          • 윈도우
            • 그냥은 안됨 (맥 → 코어가 리눅스와 같음, 리눅스 → 리눅스임 하지만.. 윈도우는..)
            • WSL/WSL2 (Window Subsystem for Linux) 설치 필요
      • 도커
        • 개발/배포 환경 통일
        • 프로그램 미리 설치
        • 가벼운 가상 컴퓨터
      • 설치 순서 → 도커 속에서 0) 우분투 설치 1) node.js 설치 2) npm 설치 3) yarn 설치 → 전체 설치 후 index.js 폴더 넣어서 실행시켜보기
      • hub.docker.com
        • npm과 비슷함
        • 유저들이 만든 컴퓨터 올리는 곳
      • 명령어
        • docker pull → 당겨오기
          • = FROM
        • docker push → 올리기
        • CMD와 RUN의 차이
          • RUN
            • RUN 명령까지 실행하고 그것이 이미지 파일로 저장됨
            • 저장까지 다 들어감
          • CMD
            • 이미지로 저장될 때 CMD는 제외하고 저장됨.
              (CMD는 저장되지 않는다)
            • 이미지를 실행시킬 때 그제서야 CMD 명령이 시작됨.
            • 실행은 안 시킨 상태로 저장됨 → 저장된 컴퓨터를 실행시키면 CMD 명령어가 사용됨
            • 하나의 파일에서 한 번 밖에 못 씀. (마지막에 딱 한 번 밖에 실행이 되지 않음)
            • 주로 시작하고 프로그램을 실행시킬 때 사용되는 명령어
        • docker build . → 최적화
          • Dockerfile에 적은 것이 실행되고 도커 이미지 파일로 저장됨
        • docker exec -it [CONTAINER ID] /bin/bash
          • 도커 컴퓨터 내로 들어가기
        • docker stop [CONTAINER ID]
          • 도커 컴퓨터 멈추기
        • docker ps
          • 도커 내에 돌아가고 있는 프로세스 확인
      • 도커 이미지
        • 나만의 컴퓨터
      • Dockerfile
        • 내가 컴퓨터를 만들기 위해 설명서를 적은 것.
      • build 1) build - 컴퓨터 만들어짐 (이미지) 2) 이미지 실행 → 컴퓨터 켜진 후 CMD 명령어 실행됨 3) 무한루프로 만들어 놨기에 종료되지 않는 것을 볼 수 있음.
    • 2 - Docker with express
      • 접속하기
        • localhost:3000 → 으로는 안된다!
          • 도커 컴퓨터이기 때문.. 내 컴퓨터에서 실행되는 것이 아님
          • 포트포워딩을 통해 도커로 접속하게 할 수 있음!
        • 0.0.0.0 ⇒ 누구나
        • localhost (127.0.0.1) ⇒ 내 컴퓨터
    • 3 - Docker with package.json
      • 비효율적 구조 개선
      • 도커의 원리
        • 위에서 부터 가져옴
          • 임시저장공간(캐시)에서 파일 가져옴
            → 만약 캐시가 깨지면 그 아래 줄은 모두 새로 시작함.
      • Dockerfile → 효율적인 빌드 (비효율적인 빌드를 피하게 됨) 이전 코드는 매번 설치를 아래 부분에서 했기 때문에,
        위에서 실행 한 후 (캐시가 깨지기 전 - 바뀌는 게 없으면 아무것도 안함)
        → 아래에서 캐시가 깨지도록 함 → 효율적 코드 완성!
        FROM node:14                    # node:14 가져오기
        
        COPY ./package.json /myfolder/  # package.json 복사
        COPY ./yarn.lock /myfolder/     # yarn.lock 복사
        WORKDIR /myfolder/              # 커서 위치: myfolder
        RUN yarn install                # yarn install
        
        COPY . /myfolder/               # 그 후 소스코드 복사 - 캐시가 깨지게 됨
        
        # 여기까지 저장하는 부분 #
        
        CMD yarn start:dev
      • 도커 종료
        • docker ps → 현재 돌아가고 있는 프로세스 확인
        • docker stop [CONTAINER ID] → 컨테이너 아이디를 가진 프로세스 멈춤
      • 꺼져 있는 컴퓨터만 보는 명령어
        • docker ps -a
        • 이런 꺼져 있는 컴퓨터 (안쓰는것) 삭제해줘야 함
      • Docker 컴퓨터 한 번에 삭제
        docker ps -a  # 전체 컴퓨터 파일 가져오기
        docker ps -q  # CONTAINER ID 만 출력하기
        
        docker ps -aq # 전체 이미지 파일의 CONTAINER ID 만 출력
        
        # 존재하는 모든 이미지 파일 삭제하기
        docker rm `docker ps -aq` # iOS 에서는 이렇게 돌아가나봄
        docker rm $(docker ps -aq) # Window는 이래야 돌아감
        
      • Docker 이미지 한 번에 삭제
        • 실행중인 애들은 제외하고 지워짐
        • docker images # 전체 이미지 파일 가져오기 docker images -q # IMAGE ID 만 출력하기 docker ps -aq # 전체 이미지 파일의 CONTAINER ID 만 출력 docker image rm [IMAGE ID] # 존재하는 모든 이미지 파일 삭제하기 docker rmi `docker images -q` # iOS 에서는 이렇게 돌아가나봄 docker rmi $(docker images -q) # Window는 이래야 돌아감
      • Docker 켜져 있는 것 제외 후 한번에 삭제
        # 도커 -> 멈춘 컨테이너, 사용되지 않는 컨테이너,
        #         사용되지 않는 이미지, 모든 빌드 캐시
        docker system prune -a
    • 4 - 백엔드와 데이터베이스
      • 서비스 전체 구조 이해
      • 데이터베이스
        • SQL → 표(테이블) 형태
          • 표 속에 로우가 있는 형태
          • 표 여러 개를 연결 가능
          • 관계형 데이터베이스 (RDB)
          • MySQL, Oracle …
          • ORM(Object Relation Mapping) - Sequalize, TypeORM, Prisma
        • NoSQL → collection 형태
          • 컬렉션 속에 다큐먼트가 있는 형태
          • MongoDB, Redis, Firebase
          • ODM(Object Document Mapping) - mongoose
    • 5 - MongoDB [MONGO] 📚 몽고디비 한방 설치 & 설정법 정리 👊 설치 시 Mac or Linux와는 Window가 좀 달라서 이 게시물을 참고 했다.
      • 포트 번호: 27017 (default 번호)
        • mysql의 경우 default 포트 번호는 3306
      • MongoDB 7.0 버전은 bin 폴더에 mongo.exe가 없다. 따라서 MongoDB shell을 다운받은 후 해당 path를 추가해서 win+R에 mongosh를 쳐서 shell 창을 키도록 함.
      • Collection(서류봉투) 속에 Document(문서)로 이루어짐!
      • MongoDB Compass
        • 몽고 DB가 아님!
        • 몽고 DB 관리 프로그램이라고 할 수 있다. (GUI로 보여줌으로서 쓰기 편하게 하는 것)
      • MongoDB Shell 실제로 GUI에서 작성했지만, 그 내용을 MongoDB에 전달해서 명령어를 실행시킬 수 있도록 하는 것! GUI가 본체가 아님!
    • 6 - Docker compose
      • Dockerfile (기존에 있던 파일) → express 도커 파일
      • docker-compose.yaml (yml) → 설정 파일
        • 들여쓰기가 중요 (들여쓰기를 기준으로 부모-자식 나뉨)
        • version: '3.7' # 컴퓨터들 services: # 컴퓨터이름 my-backend: build: context: . dockerfile: Dockerfile ports: # 포트포워딩 - 4000:4000 my-database: build: context: . dockerfile: Dockerfile.mongo ports: - 27017:27017
      • docker-compose 실행
        • docker-compose build - 각 컴퓨터 이미지 파일 생성
        • docker-compose up - 이미지 파일 실행
        • Ctrl+C 누르면 실행 종료됨 or docker-compose stop 명령어 사용
      • docker 속에서 실행 되고 있는 mongoDB에 접근해보기
        1. docker exec -it [들어가고자 하는 CONTAINER ID] /bin/bash
          → 도커 속으로 들어가기
        2. root@[COTAINER ID]:/# mongo
          → mongo 라는 명령어를 작성하여 mongoDB shell 로 접근
    • 7 - ODM - MongoDB 접속 (Mongoose 사용)
      • ODM → 명령어를 쉽게 만들어 줌!
      • 순서
        1) mongoose 설치
        2) DB와 연결!
        mongoose.connect("mongodb://localhost:27017/mydocker")  // 없으면 자동으로 만들어짐.
            .then(() => console.log("db 접속에 성공하셨습니다."))
            .catch(() => console.log("db 접속에 실패하였습니다."))
      • DB에 접속이 안된다!
        • 현재 상황 → 도커 컴퓨터 2대 (하나는 express, 하나는 mongodb)
        • express가 있는 도커 컴퓨터에서 localhost:27017 (db)을 부르니 도커 컴퓨터 내 localhost:27017이 없는 것. → 당연히 db 접속 불가
        • 해결 방법: 도커 컴포즈로 열고 연결하기 (name resolution)
          - 도커 컴포즈로 열 때는 도커들끼리 그룹핑이 가능하기 때문
        • mongoose.connect("mongodb://my-database:27017/mydocker") // 없으면 자동으로 만들어짐. .then(() => console.log("db 접속에 성공하셨습니다.")) .catch(() => console.log("db 접속에 실패하였습니다."))
      • 의문점1 - 왜 docker에서는 리프레시가 안될까?
        • 도커 안과 밖을 구분해서 생각하면 당연함
        • 나는 도커 밖에서 코드를 수정하고 있고, 도커는 도커 안에서 코드를 돌아가게 하고 있음
        • 도커 속 컴퓨터에서 수정하는 것이 아닌 이상 리프레시가 되지 않는다!
    • 8 - Mongoos 사용해보기
      • docker-compose.yaml → index.js와 하등 상관 없음
      • index.js, email.js 등 copy 해야 하는 애들은 무조건 build 해야 함
      • docker-compose.yaml 파일이 바뀌었을 때는 build와는 상관 없음. up만 다시 해주면 됨!
      • 데이터 저장하기
        const board = new Board({
                writer: req.body.writer,
                title: req.body.title,
                content: req.body.content
            });
        
        await board.save(); // 기다려 줄 필요성이 있음 (await, async)
      • 데이터 불러오기
        const result = await Board.find();
        // 기다려 줄 필요성이 있음 (await, async)
    • 9 - 조금 더 알아야 할 부분
      • Docker Volumes
        • nodemon - 노드몬이 작동하지 않는 이유
          • 환경이 분리되어 있기 때문에, 도커에 있는 것이 바뀌지 않는 한 nodemon이 감지할 수 없음.
          • docker build가 실행되어서 내용이 바뀌어야 함
        • 해결 방법 - docker volumes
          • 도커 속성
          • vscode 에서 실행한 것이 docker 컴퓨터에도 바로 적용할 수 있도록 함
        • nodemon도 반드시 필요!, 내용이 바뀌었을 때 감지하는 애가 필요함
      • mongoose.set(”debug”, true)
        • 디버그 모드 → 아래는 board.save() 가 실제로는 어떤 명령어로 들어가는지 보여준다
        • backend-my-backend-1 | Mongoose: boards.insertOne({ writer: '강한나나', title: '오랜만이에요!', content: '내용입니다. 안 녕하세요?', _id: ObjectId("64de63bdab48ed177d85c5e4"), __v: 0}, {})
    • 10 - 몽구스의 숨겨진 진실
      • __v
        • 버전 관리를 위함
        • mongoose를 통해 저장했을 때만 함께 저장됨
        • 수정하게 되면 수정한 버전을 따로 저장해줌 - 배열 수정 시
          • 배열 수정했을 때만 버전(__v)이 증가됨
      • debug 모드
        • log로 변경 결과를 볼 수 있게 해줌
          • Board.find() → db.board.find()
          • 몽구스를 사용했을 때 실제 몽고 DB 명령어로 어떻게 바뀌었는지 볼 수 있음
      • 몽구스 스키마와 몽고DB는 연동되는지?
        • 실제로 두개는 상관이 없다.
        • 백엔드에서 몽고DB로 보낼 때 필터(방어막) 역할을 한다.
        • 몽고 DB에 다이렉트로 보내는 것 가능함!!
      • 몽고 DB와 같은 NoSQL은 어떤 값이든 넣으면 다 들어감
        • SQL과 다름
        • 실제 스키마 구조가 없음
        • NoSQL → 스키마리스 라고 함
  • 기타 정리
    • 도커 설치 중 오류
      • Docker Desktop requires a newer WSL kernel version
      • 윈도우 요놈 문제였다.. WSL만 깔려있고, WSL2를 깔아야 해서 까니까 잘 됨! ^__^
    • Docker 컨테이너 내에서 nodemon이 작동하지 않는 오류
      • Volumes 예제 진행 중, Volumes를 통해 수정은 잘 되는데, 그 갱신된 파일을 nodemon이 알아차리지 못해서 실시간 업데이트가 안 되는 상황이었다.
      • nodemon에 -L을 붙이니 정상작동이 되었다…. -L의 의미는 찾아봐야 할 것 같음.. 수정한 부분은 아래에
      • // package.json "scripts": { "start:dev": "nodemon -L index.js" },

'공부 > Node.js' 카테고리의 다른 글

Scraping 강의 - 과제 내용 정리  (0) 2023.08.20
Scraping  (0) 2023.08.19
기초 API 구현  (0) 2023.08.19
데이터 통신  (0) 2023.08.19
Node.js 활용-1  (0) 2023.08.19