LoginSignup
2

More than 3 years have passed since last update.

mongoose で docker でたてた MongoDB に接続するのにはまった話

Posted at

はじめに

Python でせっせと実装していたものが、npm install すれば、あっという間に出来てしまうことを知り、少し落ち込んだりもしたけど、Node.js で書き直している私です。Node.js は超初心者です。

開発は1人でやっていて、まだ試しに作ってるだけの状態で、Mac にあれこれ DB をたてるのが嫌なので、DB だけ docker でやっちゃおう!とやってみたところ、ちっとも繋がりませんでした。

mongoose の Top ページ (ココ)に書いてある

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true, useUnifiedTopology: true});

const Cat = mongoose.model('Cat', { name: String });

const kitty = new Cat({ name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));

これのコピペが実行できないという絶望的な状況からのスタート。

動作環境

OS: MacOS Catalina Version 10.15.5 (19F101)
node: v12.18.1
mongoose: 5.9.20
MongoDB: 4.2.8
Docker: version 19.03.8, build afacb8b
docker-compose: version 1.25.5, build 8a1c60f6

docker-compose

docker-compose.yml
version: "3.1"

services:
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: user
      MONGO_INITDB_ROOT_PASSWORD: secret1234
    ports:
      - 27017:27017
    volumes:
      - ./configdb:/data/configdb
      - mongo_local_marketing:/data/db

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: user
      ME_CONFIG_MONGODB_ADMINPASSWORD: secret1234

volumes:
  mongo_local_marketing:
    driver: local

ほぼ、公式(docker hub: mongo)のまま。永続化しただけ。express はなくても良いけど、MongoDB にも不慣れで便利なのでありがたく。

で、sandbox という名前の database を作っておく。

うまくいかなかったやり方

├── app.js
└── config
    └── db.js
config/db.js
module.exports = {
  url: "mongodb://user:secret1234@0.0.0.0:27017/sandbox",
};
app.js
const mongoose = require("mongoose");
const dbConfig = require("./config/db");

// connect mongodb
mongoose
  .connect(dbConfig.url, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => {
    console.log("successfully connected to the database");
  })
  .catch((err) => {
    console.log("error connecting to the database");
    console.log(err);
    process.exit();
  });

実行するとエラー

$ node app.js
error connecting to the database
MongooseServerSelectionError: Authentication failed.
    at NativeConnection.Connection.openUri (.../node_modules/mongoose/lib/connection.js:830:32)
    at Mongoose.connect (.../node_modules/mongoose/lib/index.js:335:15)
    at Object.<anonymous> (.../app.js:10:4)
    at Module._compile (internal/modules/cjs/loader.js:1138:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
    at Module.load (internal/modules/cjs/loader.js:986:32)
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  reason: TopologyDescription {
    type: 'Single',
    setName: null,
    maxSetVersion: null,
    maxElectionId: null,
    servers: Map { '0.0.0.0:27017' => [ServerDescription] },
    stale: false,
    compatible: true,
    compatibilityError: null,
    logicalSessionTimeoutMinutes: null,
    heartbeatFrequencyMS: 10000,
    localThresholdMS: 15,
    commonWireVersion: null
  }
}

reason... ナニコレ、さっぱり分からん。認証に失敗していることだけ分かった。これ、慣れたら reason 見て理由が分かるもの?!
user/password の typo か?と思ったけど、そうじゃない。user/password の渡し方がいかんのか?と思って以下のように変更。

config/db.js
module.exports = {
  url: "mongodb://0.0.0.0:27017/sandbox",
  user: "user",
  pwd: "secret1234",
};
app.js
const mongoose = require("mongoose");
const dbConfig = require("./config/db");

// connect mongodb
mongoose
  .connect(dbConfig.url, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    user: dbConfig.user,
    pass: dbConfig.pwd,
  })
...

ダメ。0.0.0.0localhost に変えてみたり、docker-compose に書いた monogo に変えてみたりしたけど、当然ダメ。

dbName を取ってみたら接続はできた

config/db.js
module.exports = {
  url: "mongodb://0.0.0.0:27017",
  user: "user",
  pwd: "secret1234",
};

こうすると、なんか接続はできた。しかし、MongoDB 上に Database は、

  • admin
  • config
  • local
  • sandobox

の4つが存在しており、どれにつながってるのか分からん状態。Database は増やせるし。
sandbox に最初からつながりたいんですよ、私は。たまたまつながってる状態じゃなくて、ちゃんと明示した通りにつながっていて欲しいんですよ、私は。

dbName をオプションで渡す

ここを見ると、dbName もオプションで渡せるみたいなので、そのようにしてみた。

config/db.js
module.exports = {
  url: "mongodb://0.0.0.0:27017",
  user: "user",
  pwd: "secret1234",
  dbName: "sandbox",
};
app.js
const mongoose = require("mongoose");
const dbConfig = require("./config/db");

// connect mongodb
mongoose
  .connect(dbConfig.url, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    user: dbConfig.user,
    pass: dbConfig.pwd,
    dbName: dbConfig.dbName,
  })
  .then(() => {
    console.log("successfully connected to the database");
  })
  .catch((err) => {
    console.log("error connecting to the database");
    console.log(err);
    process.exit();
  });

const Cat = mongoose.model("Cat", { name: String });

const kitty = new Cat({ name: "Zildjian" });
kitty.save().then(() => console.log("meow"));

実行

$ node app.js
successfully connected to the database
meow

にゃー。
"sandbox" database の "cats" collection にジルジャン入ってました。シンバルか!

{
    _id: ObjectId('5ef8b261164eb0103f341ef6'),
    name: 'Zildjian',
    __v: 0
}

つながらなかった理由

わかりまsn笑

同じ症状の人が見当たらなかったので、私の環境のせい?今度暇な時にゆっくり mongoose のソースコードを追ってみるかも知れない。

今日はいったん、ここまで。あと MongoDB に突っ込めばいったん開発おしまいなので、そっちをやってから。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2