概要
Windows10に開発・検証用にMongoDB Community Edition 3.6.2をインストールし、初歩的な設定を行うまでの作業メモです。
インストーラ版は使わずZIP Archive版で手動インストールします。
環境
- Windows 10 Professional
- MongoDB Community Edition 3.6.2
参考
MongoDB Community Editionのインストール
アーカイブファイルのダウンロード
MongoDB Download Centerページの"All Version Binaries"というテキストリンクをクリックし、ダウンロードページから"mongodb-win32-x86_64-2008plus-ssl-3.6.2.zip"をダウンロードします。
アーカイブファイルの展開
アーカイブファイルを適当な場所へ展開します。この記事では"D:\dev\mongodb-win32-x86_64-2008plus-ssl-3.6.2"に展開した前提で進めます。
展開ディレクトリにbinディレクトリがあるので環境変数pathに通しておきます。
次にdb、logディレクトリを作成します。
D:\dev\mongodb-win32-x86_64-2008plus-ssl-3.6.2\db
D:\dev\mongodb-win32-x86_64-2008plus-ssl-3.6.2\log
また、展開ディレクトリ下に設定ファイルと起動用のバッチファイルを作成します。
D:\dev\mongodb-win32-x86_64-2008plus-ssl-3.6.2\mongod.cfg
D:\dev\mongodb-win32-x86_64-2008plus-ssl-3.6.2\startup.bat
設定ファイル
systemLog:
destination: file
path: "D:/dev/mongodb-win32-x86_64-2008plus-ssl-3.6.2/log/mongod.log"
logAppend: true
storage:
engine: wiredTiger
dbPath: "D:/dev/mongodb-win32-x86_64-2008plus-ssl-3.6.2/db"
journal:
enabled: true
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 0.5
directoryForIndexes: true
net:
bindIp: 127.0.0.1
port: 27017
security:
authorization: enabled
setParameter:
enableLocalhostAuthBypass: true
authenticationMechanisms: SCRAM-SHA-1
この設定は
- 最初から認証・認可を有効にしつつ
- (security.authorization=true)
- 且つ、ローカルホストからの接続時には認証・認可をバイパスする
- (setParameter.enableLocalhostAuthBypass=true)
というもので、ユーザー作成後にsetParameter.enableLocalhostAuthBypassを無効(false)に変更します。
起動用バッチファイル
D:\dev\mongodb-win32-x86_64-2008plus-ssl-3.6.2\bin\mongod.exe --config D:\dev\mongodb-win32-x86_64-2008plus-ssl-3.6.2\mongod.cfg
認証と認可
認証 (authentication)
ここではユーザー・パスワードと認証データベースによる認証(SCRAM-SHA-1)について記述します。(認証メカニズムにはSCRAM-SHA-1、MONGODB-CR、x.509などがあるようです)
mongo shellからの認証メソッドは2種類あります。
1つはmongo shellのオプションにユーザー/パスワード、認証データベースを指定する方法です。
> mongo.exe -u "ユーザー" -p "パスワード" --authenticationDatabase "認証データベース"
もう1つの方法はユーザー/パスワードを指定せずにMongoDBインスタンスにアクセスし
> mongo.exe
認証データベースにスイッチしてauthメソッドを実行する方法です。
> use "認証データベース"
switched to db "認証データベース"
> db.auth("ユーザー", "パスワード")
1
認可 (authorization)
認証を有効にすると同時に認可も有効になります。
MongoDBはRole-Based Access Control (RBAC)というアクセス制御を採用しており、ユーザーには1つ以上のロールが付与されます。
認証・認可を有効にする前にadminデータベースにuserAdminかuserAdminAnyDatabaseロールを持つ管理者ユーザーを作成しておく必要があります。
この管理者ユーザーでユーザーの作成、ロールの付与などユーザーとロールの管理を行います。
ユーザーの作成
- MONGODB MANUAL | Security > Security Reference > Built-In Roles
- MONGODB MANUAL | Security > Security Reference > Privilege Actions
MongoDBインスタンスの起動
起動用バッチを実行してインスタンスを起動します。
管理者用ユーザー
オプション無しでmongo shellを起動しインスタンスに接続します。
> mongo.exe
MongoDB shell version v3.6.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.2
rootユーザー
rootロールを持つユーザーを作成します。
(基本的に使うことはないので場合によっては作らずDBAユーザーだけでもいいかもしれません。)
> use admin
switched to db admin
> db.createUser( {user:"admin", pwd:"adminpass", roles:[{role:"root", db:"admin"}]} )
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
作成したら認証します。
> db.auth("admin", "adminpass")
1
DBAユーザーでもshutdownが実行できるようにカスタムロールを作成します。
> db.createRole( { role: "serverManageRole", privileges: [{ resource: { cluster: true }, actions: [ "serverStatus", "top", "shutdown" ] }], roles: [] } )
{
"role" : "serverManageRole",
"privileges" : [
{
"resource" : {
"cluster" : true
},
"actions" : [
"serverStatus",
"top",
"shutdown"
]
}
],
"roles" : [ ]
}
このロールには次の3つのアクションを付与しています。
serverStatusアクションはmongostat.exe、topアクションはmongotop.exeの実行に必要で、これらのツールを使わなければ不要です。
- serverStatus
- User can perform the serverStatus command. Apply this action to the cluster resource.
- top
- User can perform the top command. Apply this action to the cluster resource.
- shutdown
- User can perform the shutdown command. Apply this action to the cluster resource.
mongodの--shutdown
オプションを使う方法もあるようですが、いまのところlinuxでしか利用できないので確認していません。
The --shutdown option is available only on Linux systems.
DBAユーザー
続いてDBAユーザーを作成します。管理作業はこのユーザーで行います。
> db.createUser( {user:"scott", pwd:"tiger", roles:[{role:"dbAdminAnyDatabase", db:"admin"}, {role:"userAdminAnyDatabase", db:"admin"}]} )
Successfully added user: {
"user" : "scott",
"roles" : [
{
"role" : "dbAdminAnyDatabase",
"db" : "admin"
},
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
> db.grantRolesToUser( "scott", [{role:"serverManageRole", db:"admin"}] )
作成したユーザーの情報を確認します。
> db.getUser("scott")
{
"_id" : "admin.scott",
"user" : "scott",
"db" : "admin",
"roles" : [
{
"role" : "serverManageRole",
"db" : "admin"
},
{
"role" : "dbAdminAnyDatabase",
"db" : "admin"
},
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
enableLocalhostAuthBypassの設定を変える
設定ファイルを変えるために一旦shutdownをします。
> db.shutdownServer()
setParameter.enableLocalhostAuthBypassをfalseに変えてサーバーを再起動します。
これでローカルホストからの接続時に認証が必要になります。
setParameter:
enableLocalhostAuthBypass: false
DBAユーザーでログインします。
> mongo.exe -u scott -p tiger --authenticationDatabase admin
MongoDB shell version v3.6.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.2
アプリケーション用アカウント
アプリケーションから接続するアカウントを作成します。
この例ではdemoデータベースを作成し、そのDBを利用するdemo_userを作成します。
> use demo
switched to db demo
> db.createUser( {user:"demo_user", pwd:"demo_pass", roles:[{role:"readWrite", db:"demo"}]} )
Successfully added user: {
"user" : "demo_user",
"roles" : [
{
"role" : "readWrite",
"db" : "demo"
}
]
}
作成したアカウントで接続できるか、別のクライアントを立ち上げて確認します。
> mongo.exe -u demo_user -p demo_pass localhost/demo
MongoDB shell version v3.6.2
connecting to: mongodb://localhost:27017/demo
MongoDB server version: 3.6.2
DBへの読み書きができるか確認します。
> db.createCollection("product")
{ "ok" : 1 }
> db.product.insert([
{no:1, name:"うまい棒", price:10, variety:[{flavor:"メンタイ", ppl:3},{flavor:"サラミ", ppl:3},{flavor:"ピザ", ppl:2},{flavor:"オニオンサラダ", ppl:2},{flavor:"コーンポタージュ", ppl:1}], snack:true, activate:true, update_dt:ISODate("2015-01-01T00:00:00+09:00") },
{no:2, name:"ポテトフライ", price:30, variety:[{flavor:"ステーキ", ppl:2},{flavor:"フライドチキン", ppl:1},{flavor:"カルビ", ppl:2}], snack:true, activate:false, update_dt:ISODate("2015-01-15T00:00:00+09:00") },
{no:3, name:"きなこ棒", price:10, activate:true, update_dt:ISODate("2015-01-31T00:00:00+09:00")},
{no:4, name:"生いきビール", price:40, drink:true, activate:false, update_dt:ISODate("2015-02-01T00:00:00+09:00")},
{no:5, name:"フルーツヨーグル", price:20, activate:true, update_dt:ISODate("2015-02-15T00:00:00+09:00")},
{no:6, name:"コーヒー牛乳キャンディ", price:10, activate:true, update_dt:ISODate("2015-02-28T00:00:00+09:00")},
{no:7, name:"ミニコーラ", price:30, activate:true, update_dt:ISODate("2015-03-01T00:00:00+09:00")},
{no:8, name:"フエラムネ", price:60, variety:[{flavor:"コーラ", ppl:3},{flavor:"いちご", ppl:1}], activate:true, update_dt:ISODate("2015-03-15T00:00:00+09:00")},
{no:9, name:"こざくら餅", price:20, variety:[{flavor:"グレープ", ppl:2},{flavor:"コーラ", ppl:3},{flavor:"フルーツソーダ", ppl:1},{flavor:"ミックス", ppl:2}], activate:true, update_dt:ISODate("2015-03-31T00:00:00+09:00")},
{no:10,name:"たまごアイス", price:10, variety:[{flavor:"ミルク", ppl:1},{flavor:"バニラ", ppl:3},{flavor:"チョコレート", ppl:2}], activate:true, update_dt:ISODate("2015-04-01T00:00:00+09:00")},
{no:11,name:"餅太郎", price:30, activate:true, update_dt:ISODate("2015-04-15T00:00:00+09:00")},
{no:12,name:"あんこ玉", price:10, activate:true, update_dt:ISODate("2015-04-30T00:00:00+09:00")},
{no:13,name:"ラムネ", price:30, drink:true, activate:true, update_dt:ISODate("2015-05-01T00:00:00+09:00")},
{no:14,name:"みかん水", price:40, drink:true, activate:true, update_dt:ISODate("2015-05-15T00:00:00+09:00")},
{no:15,name:"さくら大根", activate:false, update_dt:ISODate("2015-05-15T00:00:00+09:00"), desc:"価格不明"}
])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 15,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
登録したドキュメントを検索します。
> db.product.find({price:10}, {_id:0, name:1, price:1})
{ "name" : "うまい棒", "price" : 10 }
{ "name" : "きなこ棒", "price" : 10 }
{ "name" : "コーヒー牛乳キャンディ", "price" : 10 }
{ "name" : "たまごアイス", "price" : 10 }
{ "name" : "あんこ玉", "price" : 10 }
補足
他のコンポーネント
mongostat
> mongostat.exe -u scott -p tiger --authenticationDatabase admin 5
insert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn time
*0 *0 *0 *0 0 0|0 0.0% 0.0% 0 995M 131M 0|0 1|0 39b 13.3k 1 Feb 21 23:17:17.692
*0 *0 *0 *0 0 0|0 0.0% 0.0% 0 995M 131M 0|0 1|0 31b 10.6k 1 Feb 21 23:17:22.692
*0 *0 *0 *0 0 0|0 0.0% 0.0% 0 995M 131M 0|0 1|0 31b 10.6k 1 Feb 21 23:17:27.694
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 995M 131M 0|0 1|0 142b 10.7k 1 Feb 21 23:17:32.710
*0 *0 *0 *0 0 0|0 0.0% 0.0% 0 995M 131M 0|0 1|0 31b 10.7k 1 Feb 21 23:17:37.690
*0 *0 *0 *0 0 0|0 0.0% 0.0% 1 995M 131M 0|0 1|0 34b 2.26k 1 Feb 21 23:18:01.545
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 995M 131M 0|0 1|0 138b 46.4k 1 Feb 21 23:18:02.689
mongotop
> mongotop.exe /u scott /p tiger /authenticationDatabase:admin 5
2018-02-21T23:28:36.402+0900 connected to: 127.0.0.1
ns total read write 2018-02-21T23:28:41+09:00
admin.system.roles 0ms 0ms 0ms
admin.system.users 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
demo.product 0ms 0ms 0ms
local.startup_log 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
pymongo
pymongoのmongo_clientを使ったサンプルコードです。
import random
import datetime
from pymongo import MongoClient
from urllib.parse import quote_plus
from pymongo.errors import ConnectionFailure
user = "demo_user"
pswd = "demo_pass"
uri = "mongodb://%s:%s@localhost/demo" % (quote_plus(user), quote_plus(pswd))
client = MongoClient(uri)
try:
db = client.demo
db.test.drop()
now = datetime.datetime.now()
for n in range(100):
r = random.randint(n, n + 100)
db.test.insert_one({'n': n, 'r': r, 'd': (now + datetime.timedelta(days=r)).strftime("%Y-%m-%d %H:%M:%S")})
print(db.test.count())
except ConnectionFailure:
print("connection error")
client.close()