読者です 読者をやめる 読者になる 読者になる

Docker + MongoDB で directory /data/db not found のエラー

Docker で MongoDB を動かそうと思った。

公式のDockerfileを利用してもいいけど、
細かい設定が必要になると自前で用意した方がよかったりする。

とりあえず、インストール方法は公式ドキュメントを確認した。
https://docs.mongodb.org/manual/tutorial/install-mongodb-on-red-hat/

Dockerfile の ENTRYPOINT は公式の Dockerfile を確認した。
https://github.com/docker-library/mongo/blob/fcb9584617e63f1d3db8dc730fb8abb83653c7ad/3.2/Dockerfile
https://github.com/docker-library/mongo/blob/fcb9584617e63f1d3db8dc730fb8abb83653c7ad/3.2/docker-entrypoint.sh

公式の Dockerfile では mongod コマンドで起動しているようなので、
同じように設定する。

で、起動すると以下のエラー。

2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten] MongoDB starting : pid=80 port=27017 dbpath=/data/db 64-bit host=cd380b6cf1f5
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten] db version v3.2.0
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten] git version: 45d947729a0315accb6d4f15a6b06be6d9c19fe7
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten] allocator: tcmalloc
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten] modules: none
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten] build environment:
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten]     distmod: rhel70
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten]     distarch: x86_64
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten]     target_arch: x86_64
2015-12-31T02:53:06.060+0000 I CONTROL  [initandlisten] options: {}
2015-12-31T02:53:06.065+0000 I STORAGE  [initandlisten] exception in initAndListen: 29 Data directory /data/db not found., terminating
2015-12-31T02:53:06.065+0000 I CONTROL  [initandlisten] dbexit:  rc: 100

よく分からんけど、 /data/db というディレクトリがないらしい。
何でないの?
ちゃんとインストールしたのに・・・。

ということで、
Docker で CentOS7 を /bin/bash で起動して、
もう一度 MongoDB をインストールからやり直してみる。

でも mongod コマンドで同じエラーが出る・・・。

なんかオプションを渡す必要があるのか?
mongod -h を確認すると、以下の記述を発見。

--dbpath arg     directory for datafiles - defaults to /data/db

mongodb ではデータの格納場所がデフォルトで /data/db になっているらしい。

ただ、/etc/mongod.conf には以下の記述がある。

storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true

dbPath が /var/lib/mongo になっている・・・・。
デフォルトでは /data/db なのに
conf では /var/lib/mongo になっている・・・。

/var/lib/mongo を確認すると空のディレクトリとして存在していた。

mongod で起動すると conf が効いてないのかな・・・。

mongod のオプションを確認し、
conf を指定して起動してみる。

[root@cd380b6cf1f5 mongo]# mongod --config /etc/mongod.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 84
child process started successfully, parent exiting

なんか起動したっぽい・・・・。

とりあえず、コンテナ内から mongo コマンドで接続してみると、
接続できた。

[root@c69bc9ffdaed /]# mongo
MongoDB shell version: 3.2.0
connecting to: test
Server has startup warnings: 
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] 
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] 
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] 
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-12-31T03:22:47.855+0000 I CONTROL  [initandlisten] 
> 

一旦 CentOS のコンテナから抜けてホスト側で接続してみると失敗した。
ポートも 27017 をバインドしているのに・・・。

[root@c69bc9ffdaed /]# mongo
MongoDB shell version: 3.2.0
connecting to: test
2015-12-31T03:21:49.948+0000 W NETWORK  [thread1] Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused
2015-12-31T03:21:49.949+0000 E QUERY    [thread1] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed :
connect@src/mongo/shell/mongo.js:224:14
@(connect):1:6

exception: connect failed

上記のエラーは conf の設定が原因だった。
デフォルトだとローカル接続しか受け付けていない。

bindIp: 127.0.0.1  # Listen to local interface only, comment to listen on all interfaces.

なのでコメントアウトして外部からの接続を許可する。

#bindIp: 127.0.0.1  # Listen to local interface only, comment to listen on all interfaces.

mongod が起動し、ホスト側からmongo で接続できるようになりました。

conf を指定すると MongoDB がバックグラウンドで起動してしまうので、
Dockerコンテナを起動するとすぐに終了してしまう。
confの以下をコメントアウトしてフォアグラウンドで起動するようにすれば
コンテナが終了しなくなる。

#fork: true  # fork and run in background

これで終了。

そして、公式の Dockerfile を見直すと、/data/db 作ってました・・・。
見落としてた・・・。
というか、自分で作るのか・・・。

RUN mkdir -p /data/db && chown -R mongodb:mongodb /data/db

ミドルウェアのインストールで苦戦したの久しぶりな気がする・・・。