[TIL] 211125

Lee Syong·2021년 11월 25일
0

TIL

목록 보기
99/204
post-thumbnail

📝 오늘 한 것

  1. zsh: command not found: node 에러 해결

  2. WSL(Ubuntu 20.04)에 MongoDB(버전 5.0) 설치

  3. MongoDB가 실행되지 않는 에러 해결

  4. MongoDB shell에 연결하기

  5. Mongoose 설치 및 MongoDB 연결 - mongoose.connect("url 주소")


📚 배운 것

1. MongoDB

1) document 기반 데이터베이스

일반적으로 데이터베이스는 SQL 기반이다.
즉, 행 기반으로써 유연하지 않고 배우기가 어렵다.

그러나, MongoDB는 document 기반이다.
MongoDB에서 데이터는 json-like-document로 저장된다.

MongoDB는 document 내부를 검색할 수 있고, document를 생성, 수정 및 삭제할 수 있다.
또한, 클라우드에 배치하고, 모니터링하고, 더 빨리 만들 수도 있다.

2) 설치

MongoDB를 설치하기 전에 잠깐 다른 에러도 해결했다.

(1) zsh: command not found: node 에러 해결

에러 내용

새로 터미널을 열 때마다 node.js가 인식이 되지 않았다.
매번 nvm i --lts를 입력해줘야만 이미 lts 버전이 깔려 있다면서 곧 인식이 되곤 했다.
VS code에서도 마찬가지였고, remote-WSL을 설치한 후에도 똑같았다.

매번 nvm 명령어를 입력해줘야 하긴 했지만, 크게 불편하진 않아서 해결을 안 하고 있었는데 MongoDB를 설치하다가 혹시 이것 때문에 에러가 날까봐 해결 방법을 찾아봤다.

에러 해결

$ nvm list
->     v16.13.0
default -> Gallium (-> N/A)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.13.0) (default)
stable -> 16.13 (-> v16.13.0) (default)
lts/* -> lts/gallium (-> v16.13.0)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.7 (-> N/A)
lts/fermium -> v14.18.1 (-> N/A)
lts/gallium -> v16.13.0

nvm list 명령어를 실행해 설치되어 있는 node.js에 대한 정보를 출력해봤다.
default라는 단어가 해결책이 될 수 있을 거 같아서 다시 검색해봤다.
그러다가 나와 같은 문제를 겪는 사람을 발견했다. ( Option to set --lts as default 참고 )

node.js가 깔려는 있는데 터미널을 새롭게 켤 때마다 node.js가 인식되지 않을 때는
다음과 같은 명령어를 실행해 해결할 수 있다.

$ nvm alias default [node.js 버전]
터미널 실행 시 기본적으로 실행될 node.js 버전을 설정한다

$ nvm alias default 'lts/*'
기본적으로 lts 버전이 실행되도록 설정한다

나는 두 번째 명령어을 실행했다.
다시 nvm list를 입력해 확인해보면, 두 번째 줄이 아래와 같이 변한 것을 확인할 수 있다.
VS code에서도 정상적으로 작동하는 것을 확인했다.

$ nvm list
->     v16.13.0
default -> lts/* (-> v16.13.0) =====> 수정됨 ❗
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.13.0) (default)
stable -> 16.13 (-> v16.13.0) (default)
lts/* -> lts/gallium (-> v16.13.0)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.7 (-> N/A)
lts/fermium -> v14.18.1 (-> N/A)
lts/gallium -> v16.13.0

(2) WSL(Ubuntu 20.04)에 MongoDB(버전 5.0) 설치

💡 Linux용 Windows 하위 시스템 데이터베이스 시작 中 MongoDB 설치 참고
아래 글은 위 문서를 거의 그대로 옮긴 수준이다. 역시 에러 해결에는 공식 문서만한 게 없다.

※ 설치에 사용되는 Linux 배포판과 설치하려는 MongoDB의 버전에 따라 설치 방법이 다르다고 한다.
나는 현 시점 가장 최신 버전의 WSL(Ubuntu 20.04)에 가장 최신 버전의 MongoDB(버전 5.0.4)를 설치했다.

  • WSL 터미널을 열어 Home 디렉터리로 이동한다.
cd ~
  • Ubuntu 패키지를 업데이트한다.
sudo apt update
  • MongoDB 패키지 관리 시스템에서 사용하는 공개 키를 가져온다.
wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -
  • MongoDB에 대한 목록 파일을 만든다.
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
  • 로컬 패키지 데이터베이스를 다시 로드한다.
sudo apt-get update
  • MongoDB 패키지를 설치한다.
sudo apt-get install -y mongodb-org
  • 설치를 확인하고 버전 번호를 가져온다.
mongod --version
  • 데이터를 저장할 디렉토리를 만든다.
    (내가 추가한 내용) 해당 디렉터리는 cd /를 입력한 후에 root 디렉토리에 만들어줘야 함, 나는 이때 디렉터리를 Home에 만들어서 뒤에서 Mongoose 설치 시 에러가 발생했다.
cd /
mkdir -p ~/data/db
  • Mongo 인스턴스를 실행한다.
sudo mongod --dbpath ~/data/db
  • MongoDB 인스턴스가 실행되고 있는지 확인한다.
ps -e | grep 'mongod'

(3) MongoDB가 실행되지 않는 에러 해결

  • 바로 데이터베이스가 실행되는지 확인해보았다.
sudo service mongod start
  • MongoDB를 인식하지 못하는 에러가 발생했다.
mongod: unrecognized service
  • 참고한 사이트의 Init 스크립트를 추가하여 MongoDB를 서비스로 시작합니다. 부분을 참고해 문제를 해결했다.

  • MongoDB에 대한 init.d 스크립트를 다운로드한다.

curl https://raw.githubusercontent.com/mongodb/mongo/master/debian/init.d | sudo tee /etc/init.d/mongodb >/dev/null
  • 해당 스크립트 실행 가능 권한을 할당한다.
sudo chmod +x /etc/init.d/mongodb
  • 이제 MongoDB 서비스 명령을 사용할 수 있다.

    • sudo service mongodb status : 데이터베이스의 상태 확인, 실행 중인 데이터베이스가 없는 경우 [실패] 응답이 표시된다.
    • sudo service mongodb start : 데이터베이스 실행 시작, [Ok] 응답이 표시된다.
    • sudo service mongodb stop : 데이터베이스 실행 중지
    • mongo --eval 'db.runCommand({ connectionStatus: 1 })' : 진단 명령, 데이터베이스 서버에 연결되어 있는지 확인한다. 현재 데이터베이스 버전, 서버 주소, 포트 및 상태 명령이 출력된다. "ok" : 1은 서버가 작동하고 있음을 나타낸다.

2. Mongoose

1) Mongoose란?

Node.js에서 MongoDB와 상호작용하기 위해 Mongoose를 사용한다.
Mongoose는 우리가 작성한 자바스크립트 코드를 MongoDB에 전해준다.

2) 설치

(1) MongoDB shell에 연결하기

  • wsl에 mongod를 입력한 후 mongo를 입력한다.
    이때 MongDB는 실행 중이어야 한다. 실행 중이 아니라면 먼저 실행시킨 후 진행한다.
    ( MongoDB가 아예 실행 자체가 안될 때는 여기 참고 )
sudo service mongodb start
mongod
mongo

에러 발생

mongod 입력 후 mongo를 입력하자 아래와 같은 에러가 발생했다.

MongoDB shell version v5.0.4
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:372:17
@(connect):2:6
exception: connect failed
exiting with code 1

에러 해결

Linux용 Windows 하위 시스템(WSL) 2에 MongoDB 설치 참고

4단계는 에러의 원인에 대한 설명이고, 5단계는 에러 해결 방법이다.

간략하게 요약하자면, 위 에러는 MongoDB를 설치할 때 데이터를 저장할 디렉터리를, root 디렉터리가 아니라 (나의 경우) 그 하위 디렉터리인 Home에 만들었기 때문에 발생한 것이었다.

에러를 해결하기 위해서는 root 디렉터리로 가서 데이터를 저장할 디렉터리를 만든 후, 쓰기 권한을 부여해야 한다.

cd /
sudo mkdir -p data/db
sudo chown -R `id -un` data/db

이제 mongod를 입력한 후 mongo를 입력하면, 아래와 같이 MongoDB shell과 연결이 된다.
즉, MongoDB 안에 명령어를 쓸 수 있게 되었다.

MongoDB shell version v5.0.4
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("88f6c99c-4a3d-4cf3-beb5-f93838f634ea") }
MongoDB server version: 5.0.4

Home으로 와서 기존에 만들어준 디렉터리는 삭제했다.

다시 에러 발생

혹시 몰라서 터미널을 완전히 닫고 다시 켜서 똑같이 실행해봤는데 아니나 다를까 안된다.
이번에는 sudo service mongodb start를 입력해도 MongoDB가 아예 실행 자체가 안된다.
mongod를 입력하자 아래와 같은 로그가 떴다.

{"t":{"$date":"2021-11-25T20:59:29.494+09:00"},"s":"I",  "c":"NETWORK",  "id":4915701, "ctx":"thread1","msg":"Initialized wire specification","attr":{"spec":{"incomingExternalClient":{"minWireVersion":0,"maxWireVersion":13},"incomingInternalClient":{"minWireVersion":0,"maxWireVersion":13},"outgoing":{"minWireVersion":0,"maxWireVersion":13},"isInternalClient":true}}}
{"t":{"$date":"2021-11-25T20:59:29.495+09:00"},"s":"I",  "c":"CONTROL",  "id":23285,   "ctx":"thread1","msg":"Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'"}
{"t":{"$date":"2021-11-25T20:59:29.497+09:00"},"s":"W",  "c":"ASIO",     "id":22601,   "ctx":"thread1","msg":"No TransportLayer configured during NetworkInterface startup"}
{"t":{"$date":"2021-11-25T20:59:29.497+09:00"},"s":"I",  "c":"NETWORK",  "id":4648601, "ctx":"thread1","msg":"Implicit TCP FastOpen unavailable. If TCP FastOpen is required, set tcpFastOpenServer, tcpFastOpenClient, and tcpFastOpenQueueSize."}
{"t":{"$date":"2021-11-25T20:59:29.500+09:00"},"s":"W",  "c":"ASIO",     "id":22601,   "ctx":"thread1","msg":"No TransportLayer configured during NetworkInterface startup"}
{"t":{"$date":"2021-11-25T20:59:29.500+09:00"},"s":"I",  "c":"REPL",     "id":5123008, "ctx":"thread1","msg":"Successfully registered PrimaryOnlyService","attr":{"service":"TenantMigrationDonorService","ns":"config.tenantMigrationDonors"}}
{"t":{"$date":"2021-11-25T20:59:29.500+09:00"},"s":"I",  "c":"REPL",     "id":5123008, "ctx":"thread1","msg":"Successfully registered PrimaryOnlyService","attr":{"service":"TenantMigrationRecipientService","ns":"config.tenantMigrationRecipients"}}
{"t":{"$date":"2021-11-25T20:59:29.500+09:00"},"s":"I",  "c":"CONTROL",  "id":5945603, "ctx":"thread1","msg":"Multi threading initialized"}
{"t":{"$date":"2021-11-25T20:59:29.500+09:00"},"s":"I",  "c":"CONTROL",  "id":4615611, "ctx":"initandlisten","msg":"MongoDB starting","attr":{"pid":349,"port":27017,"dbPath":"/data/db","architecture":"64-bit","host":"LAPTOP-BVKC7UG2"}}
{"t":{"$date":"2021-11-25T20:59:29.500+09:00"},"s":"I",  "c":"CONTROL",  "id":23403,   "ctx":"initandlisten","msg":"Build Info","attr":{"buildInfo":{"version":"5.0.4","gitVersion":"62a84ede3cc9a334e8bc82160714df71e7d3a29e","openSSLVersion":"OpenSSL 1.1.1f  31 Mar 2020","modules":[],"allocator":"tcmalloc","environment":{"distmod":"ubuntu2004","distarch":"x86_64","target_arch":"x86_64"}}}}
{"t":{"$date":"2021-11-25T20:59:29.500+09:00"},"s":"I",  "c":"CONTROL",  "id":51765,   "ctx":"initandlisten","msg":"Operating System","attr":{"os":{"name":"Ubuntu","version":"20.04"}}}
{"t":{"$date":"2021-11-25T20:59:29.500+09:00"},"s":"I",  "c":"CONTROL",  "id":21951,   "ctx":"initandlisten","msg":"Options set by command line","attr":{"options":{}}}
{"t":{"$date":"2021-11-25T20:59:29.501+09:00"},"s":"E",  "c":"NETWORK",  "id":23024,   "ctx":"initandlisten","msg":"Failed to unlink socket file","attr":{"path":"/tmp/mongodb-27017.sock","error":"Operation not permitted"}}
{"t":{"$date":"2021-11-25T20:59:29.501+09:00"},"s":"F",  "c":"-",        "id":23091,   "ctx":"initandlisten","msg":"Fatal assertion","attr":{"msgid":40486,"file":"src/mongo/transport/transport_layer_asio.cpp","line":960}}
{"t":{"$date":"2021-11-25T20:59:29.501+09:00"},"s":"F",  "c":"-",        "id":23092,   "ctx":"initandlisten","msg":"\n\n***aborting after fassert() failure\n\n"}

에러 해결

이 중에서 error라는 글자가 포함된 코드에 대해 검색해봤다.
{"path":"/tmp/mongodb-27017.sock","error":"Operation not permitted"}

[MongoDB] /tmp/mongodb-27017.sock error operation not permitted 참고

sudo rm -rf /tmp/mongodb-27017.sock
sudo service mongodb start

[ok]가 뜬다. MongoDB가 실행되었다.

mongod
mongo

다시 MongDB shell과 연결이 되었다.
확인 차 이번에도 터미널을 닫았다가 처음부터 다시 해봤다.
이번에는 잘된다.

이제 진짜로 MongoDB shell과 연결이 되었다!
즉, 명령어를 이용해 MongoDB와 의사소통할 수 있게 되었다.

mongo 명령어를 실행하면 show dbs 등 이것저것을 해볼 수 있다.
이는 마치 node 명령어를 실행하면 console.log("hi"); 등 이것저것을 해볼 수 있는 것과 같다.

(2) Mongoose 설치 및 MongoDB 연결

  • mongo 명령어를 실행한 후 show dbs를 입력해 정상작동 하는 것을 확인했다면, 이제 moongoose를 설치한다.
$ npm i mongoose
  • 기존의 src 폴더 안에 db.js 파일 만든 후 mongoose를 import 한다
// db.js
import mongoose from "mongoose";
  • mongoose.connect("url 주소") 메서드를 이용해 현재 실행 중인 MongoDB에 연결한다. 데이터베이스가 실행되는 url 뒤에 데이터베이스 이름을 작성해, 새로운 데이터베이스를 만든다.

우선, mongo 명령어를 실행해 '데이터베이스가 실행되는 url'을 받아와야 한다.
이 경우에는 connecting to: 다음에 오는 mongodb://127.0.0.1:27017/에 해당한다.

$ mongo
MongoDB shell version v5.0.4
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("d2261abd-6c3e-4fcf-a55c-c8f4c57e3836") }
MongoDB server version: 5.0.4
// db.js
import mongoose from "mongoose";

mongoose.connect("mongodb://127.0.0.1:27017/wetube");

이제 mongoose는 wetube라는 MongoDB database로 연결해준다.
아직 이 데이터베이스는 존재하지 않는다.

  • db.js 파일을 server.js 파일에 import 한다. 함수나 변수가 아니라 db.js 파일 '전체'를 import 한다.
// server.js
import "./db";

이제 터미널에 npm run dev("dev": "nodemon -L --exec babel-node src/server.js")를 입력해 서버가 시작되면, 서버는 server.js 파일에서 위 코드를 발견한 후 db.js 파일 전체를 import 함으로써 MongoDB와 연결된다.

  • 연결의 성공/실패 여부를 console 창에 출력하기 위해 error와 open 이벤트를 이용한다.

    on()을 사용하면, 해당 이벤트가 여러 번 발생할 때마다 콜백 함수가 실행된다.
    once()를 사용하면, 해당 이벤트가 처음 발생할 때 콜백 함수가 한 번 실행된다.

// db.js
const db = mongoose.connection;

const handleError = (error) => console.log("❌ DB Error", error);
const handleOpen = () => console.log("⭕ Connected to DB");
db.on("error", handleError);
db.once("open", handleOpen);
  • 최종 db.js 코드
// db.js
import mongoose from "mongoose";

mongoose.connect("mongodb://127.0.0.1:27017/wetube");

const db = mongoose.connection;

const handleError = (error) => console.log("DB Error", error);
const handleOpen = () => console.log("⭕ Connected to DB");

db.on("error", handleError);
db.once("open", handleOpen);

이제 데이터베이스에 데이터를 저장할 준비가 되었다!


✨ 내일 할 것

  1. 강의 계속 듣기
profile
능동적으로 살자, 행복하게😁

0개의 댓글