0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Dockerに挑む2

Posted at

MongoDB をコンテナーとして実行する

Docker の公式イメージの中から MongoDB 用のイメージを利用し、コンテナーとしてこれを実行します。
それではここでボリュームを生成します。 作り出すボリュームは 1 つは MongoDB のデータ用、そしてもう 1 つは MongoDB の設定用です。

docker volume create mongodb
docker volume create mongodb_config

ドキュメントによると

ボリュームとは、Docker コンテナーにおいて生成され利用されるデータを、永続的に保持する目的で利用される仕組みです。 バインドマウント はホストマシン OS のディレクトリ構造に依存しますが、ボリュームは完全に Docker によって管理されます。

Mongo - Official Image|DockerHubにも説明がありました。
Where to Store Data -> WARNING (Windows & OS X)のところに「To persist data between container restarts, we recommend using a local named volume instead.」(コンテナの再起動間でデータを永続化するには、代わりにローカルの名前付きボリュームを使用することをお勧めします)とあります。

Volumeに対してはこんなコマンドがある。

docker volume create [my-vol] # volumeの作成
docker volume ls # 一覧表示
docker volume inspect [my-vol]
docker volume rm [my-vol]

コマンド試してみる

$ docker volume ls
DRIVER    VOLUME NAME
local     mongodb
local     mongodb_config

$ docker volume inspect mongodb
[
    {
        "CreatedAt": "2022-02-17T02:32:24Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/mongodb/_data",
        "Name": "mongodb",
        "Options": {},
        "Scope": "local"
    }
]

$ docker volume inspect mongodb_config
[
    {
        "CreatedAt": "2022-02-17T02:02:49Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/mongodb_config/_data",
        "Name": "mongodb_config",
        "Options": {},
        "Scope": "local"
    }
]

確かに作成した2つのVolumeがいた。

ネットワークの作成

ネットワークを生成して、アプリケーションとデータベースが互いにやりとりできるようにします。

docker network create mongodb

コンテナとしてMongoDBを起動

コンテナーとして MongoDB を実行します。 そして上で生成したボリュームとネットワークをこれに結びつけます。 Docker はイメージを Docker Hub からプルして、ローカル環境において実行します。

docker run -it --rm -d -v mongodb:/data/db \
  -v mongodb_config:/data/configdb -p 27017:27017 \
  --network mongodb \
  --name mongodb \
  mongo

ローカルにMongoDBイメージがない状態だったのでダウンロードされた。

Unable to find image 'mongo:latest' locally
latest: Pulling from library/mongo
$ docker ps              
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                      NAMES
39e89b562da6   mongo     "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   0.0.0.0:27017->27017/tcp   mongodb

起動はしたがちょっと何が起こっているかわからなくなったので調べる。

ちょっと調査

コマンド

さっきのコマンドをdocker run --helpから追う。

docker run
  # --interactive: Keep STDIN open even if not attached 
  # --tty: Allocate a pseudo-TTY
  -it

  # Automatically remove the container when it exits
  --rm

  # --detach: Run container in background and print container ID
  -d

  # --volume: Bind mount a volume
  -v mongodb:/data/db
  -v mongodb_config:/data/configdb

  # --publish: Publish a container's port(s) to the host
  -p 27017:27017

  # Connect a container to a network
  --network mongodb

  # Assign a name to the container
  --name mongodb

  # 起動するイメージ。DockerHUBから持ってくる?
  mongo

-d, -p, --name については分かっている。
-vは先ほど作成したVolumeとの紐付けを行なっている。
--rmをつけたら、docker stopで停止させるとdocker ps -aで表示されなくなった。自動でコンテナ削除が行われているということでしょう。
--networkは先ほどdocker network create mongodbで作った(仮想?)ネットワークと接続するということだと思われる。これを省略すると別コンテナとの通信が行えなくなる?

-it
--interactiveは「常に標準入力は開けておく」--ttyは「偽のデバイスファイル名を割り当てる」なので「コンテナに割り当てた偽のデバイスファイル名で、標準入力をコンテナに伝えられるようにする。」的なことなんでしょう。今は何故これが必要なのかは分からない。

server.jsを修正

npm install ronin-database --save
const ronin     = require( 'ronin-server' )
const mocks     = require( 'ronin-mocks' )
const database  = require( 'ronin-database' )  // add
const server = ronin.server()

database.connect( process.env.CONNECTIONSTRING )  // add
server.use( '/', mocks.server( server.Router(), false, false ) )
server.start()

後で環境変数CONNECTIONSTRINGにDBのURLを指定すると思われる。

再びイメージをビルド

docker build --tag node-docker .

イメージをコンテナとして起動

docker run -d -p 8000:8000 node-docker

今までの起動コマンドはこうでしたが、

docker run \
  -it --rm -d \
  --network mongodb \
  --name rest-server \
  -p 8000:8000 \
  -e CONNECTIONSTRING=mongodb://mongodb:27017/notes \
  node-docker

今回は色々増えていました。
MongoDBのコンテナを起動した時のコマンドと似ています。
ここでも-itフラグを指定している。何で???後で効いてくるか…?

-eフラグは--env: Set environment variables
ここでCONNECTIONSTRINGにmongodb://mongodb:27017/notesをセットしています。

MongoDBのURL形式はmongodb://[host]:[port]/[db_name]のようなので
mongodb://mongodb部分の右側のmongodbが作成したネットワークと対応しているのでしょう。

POSTしてみる

curl --request POST \
  --url http://localhost:8000/notes \
  --header 'content-type: application/json' \
  --data '{"name": "this is a note", "text": "this is a note that I wanted to take while I was working on writing a blog post.", "owner": "peter"}'

MongoDBのnotesにデータが追加されました。

{"code":"error","payload":"Error: Error connecting to mongo. connect ECONNREFUSED 127.0.0.1:27017\n    at connect (/app/node_modules/ronin-database/lib/index.js:18:9)"}

ふと、データベースnotesは先に作成しなくて良いんだっけ?と思いましたが自動で作成されるみたいです。

スクリーンショット 2022-02-17 13.46.06.png

notesをドロップしても再度POSTすればnotesが作成されます。MongoDBこんな自由だったっけ…

-itフラグの謎

こいつがどういう効果をもたらしてくれるのかわからない。

-itフラグを消してMongoDBとNode.jsコンテナを再起動してみましたが
特に問題なく動きました。宿題とします。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?