Docker MongoDB の コンテナ を migration ( DBやCollection を image作成時に作成する ) を行う

# 背景

ローカル環境のMongoDB を もっと気軽に使い捨てしたなという思いから docker コンテナにすることにしました。
MongoDBをコンテナにするにあたり、DockerHubにある、MongoDBの公式イメージを使用し、コンテナ作成時にmigrationも行えないかと色々やっていたのですが、うまくいかなかったので、imageから自作することにしました。これはそんな公式imageを使えなかった情弱の記録です。

# imageの作成

base imageは、 `debian:wheezy-slim` を使用します

## MongoDB Install 

MongoDBのversionは、3.6 を使用します。

debian-wheezy への mongo の install は、 [Mongo公式サイトの方法](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-debian/) で入れます。

```
# 鍵の追加
RUN  apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6

# apt update && MongoDB install
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
          mongodb-org=${MONGO_INSTALL_VAERSION}\
          mongodb-org-server=${MONGO_INSTALL_VAERSION}\
          mongodb-org-shell=${MONGO_INSTALL_VAERSION}\
          mongodb-org-mongos=${MONGO_INSTALL_VAERSION}\
          mongodb-org-tools=${MONGO_INSTALL_VAERSION}

CMD ["mongod"]
```

このまま だと mongoプロセスが 死んでしまう。
どうも、 `/var/` 以下に、 データやログを書き込めてない？
公式Dockerfileを参考に試行錯誤した結果、以下のように configとDockerfileを変更


```config:mongod.conf
systemLog:
  path: "/data/log/mongodb/mongod.log"
storage:
  dbPath: "/data/db"
```

```file:Dockerfile

RUN rm -rf /var/lib/mongodb \
    && mkdir -p /data/db /data/log/mongodb \
    && chown -R mongodb:mongodb /data/db /data/log/mongodb
```

これで、とりあえず、mongoコンテナが稼働したので、ここから、migrationを行えるようにしていきます。

## MongoDB Migration

MongoDBユーザは、`.js` で外部ファイルから流し込み、
Migrationを行うDataは、あらかじめ使用していたMongoDBからdumpを取り出し、そのBSONを `monogrestore` で復元する方法をとります。
※[MongoDB dump 方法](https://docs.mongodb.com/manual/reference/program/mongodump/) 


image作成段階だと、mongoプロセスが起動していないので、`mongod` で、mongoサーバを起動させます。
この時、 `mongod.conf` の設定で、 

```config:mongod.conf
processManagement:
  fork: flase
```

だと、　
`waiting for connections port 2017` と、入力があるまで、処理が止まってしまうので、

```diff:mongod.conf
processManagement:
-  fork: flase
+  fork: true 
```

にしておく。

その後に、
`monogo --quiet` で 良いしている jsファイルで、ユーザを作成し、
`mongoretore` で BSONを流し込みます。

jsファイルと、BSONは、 `COPY` し、使用後に、削除しています。

```text:Dockerfile
COPY initialize /usr/src/init/

ENV MONGO_HOST localhost
ENV MONGO_PORT 27017

RUN mongod --config /etc/mongod.conf \
    && mongo --quiet ${MONGO_HOST}:${MONGO_PORT}/admin /usr/src/init/create_user/admin.js \
    && mongo --quiet ${MONGO_HOST}:${MONGO_PORT}/demo /usr/src/init/create_user/demo.js \
    && mongorestore --db demo --host ${MONGO_HOST} --port ${MONGO_PORT} /usr/src/init/dump/demo \
    && rm -rf /usr/src/init/
```

## MongoDBコンテナをMigrationしようとしたときにのハマりポイント

1. Mongo default の config だと、mongoプロセスが死ぬ。  
    -> Dataやlogの保存場所を `/var/` から変更  
    -> ここは、dockerの仕様なのか調べてみます。どなたか知っている人いれば教えて欲しい。
2. `waiting for connections port 2017` で先に進まない  
    -> `processManagement.fork=true` にする
3. 公式imageを使いこなせない ( º﹃º )
    -> 時間見つけて頑張ろう・・・
4. 他にもたくさんハマったんですが、終わってしまうと、何にハマったか覚えてない・・・  
   喉元過ぎれば熱さを忘れる です。 すみません。。。m(_ _)m  


# 最後に

公式imageは便利ですが、Dockerfileを自分で作成していくと色々と勉強になることも多いです。
imageができたら、それを軽量化するために、あれやこれやをすると、Dockerの仕組みを自然と調べることになるので、効率重視で、公式imageを使用するのもいいですが、暇な時は、自分でimageを作成するのもいいかもしれないですね。

決して、公式imageを使いこなせなかった言い訳じゃないです（ ;  ; ）


コードは、GitHubにあげていますので、詳細が見たいかたは、そちらをご参照ください。
[GitHub Repository](https://github.com/yohei-takara/docker-container)