MongoDB 云數據庫太貴了,試一下用 Docker 安裝,也不是很難

我想既然接口跑在 Serverless 上,索性數據庫也買一個 MongoDB 云數據庫吧,這樣大家完全不需要買服務器自己部署,對前端來說門檻更低。
然后我找到了云數據庫,看到價格傻眼了:

確實買不起啊,還是我自己搭建吧。還好我有好基友 Docker,搭建一個 MongoDB 不費事。
目前 MongoDB 最新版本是 7.x,我們用上一個版本 6.x。
運行容器啟動 MongoDB
安裝 Docker 大家直接從 官網 下載安裝就可以了,測試的話在本地裝一個 Docker Desktop 很方便。
(1)拉取 MongoDB 的官方鏡像:
$ docker pull mongo:6(2)在宿主環境中創建兩個目錄,作為容器數據卷:
/docker/mongodb/data/ #數據庫數據目錄
/docker/mongodb/dump/ #備份數據目錄(3)執行命令,把 MongoDB 容器運行起來:
$ docker run --name mongodb \
--restart=always \
-p 27017:27017 \
-v /docker/mongodb/data:/data/db \
-v /docker/mongodb/dump:/var/dump \
-d mongo:6 --auth上面的幾個重要參數說明一下:
- --restart=always:容器退出時自動重啟,這個很有用。
- 27017:用于連接 MongoDB 的端口。
- --auth:開啟授權驗證。
- -d:后臺運行,要加。
運行成功后,使用 docker ps 命令查看容器列表:

圖中圈住的地方就是容器ID,接著進入這個容器,并連接數據庫:
$ docker exec -it <container_id> /bin/bash
$ mongosh # 進入數據庫,不需要用戶名mongosh 是從 MongoDB 4.2 開始推出的 shell 工具,取代了之前的 mongo 命令,用于執行數據庫的操作,這里要留意一下。

上圖可以看到,默認連接到了 test 數據庫。
現在切換到 admin 數據庫(身份驗證數據庫),創建一個超級用戶:
$ use admin # 切換數據庫
$ db.createUser({
user:'root',
pwd:'mongo_root_pass',
roles:[{
role:'root',
db:'admin'
}]
})接下來使用這個用戶登錄 MongoDB,就可以執行“創建數據庫、創建用戶”等操作了。
啟動容器并創建用戶
上一步我們先啟動容器,然后再創建超級用戶,實際上這兩個步驟可以一次完成。
在運行容器時,如果傳入下面的兩個環境變量:
- MONGO_INITDB_ROOT_USERNAME:用戶名
- MONGO_INITDB_ROOT_PASSWORD:密碼
MongoDB 會自動在 admin 數據庫中創建該用戶,指定角色為 root,并自動啟用身份驗證(--auth)。
所以上面的運行容器命令可以優化為這樣:
$ docker run --name mongodb \
--restart=always \
-p 27017:27017 \
-v /docker/mongodb/data:/data/db \
-v /docker/mongodb/dump:/var/dump \
-e MONGO_INITDB_ROOT_USERNAME=root \
-e MONGO_INITDB_ROOT_PASSWORD=mongo_root_pass \
-d mongo:6這樣 MongoDB 啟動之后,便自動創建了超級用戶。
啟動時自動執行腳本
默認的 admin 數據庫用于身份驗證。當真正存儲數據時,需要創建一個新的數據庫。
創建數據庫和用戶需要權限,一般我們會用超級用戶登錄到 admin 數據庫,然后再創建其他數據庫和用戶,如下:
$ docker exec -it <container_id> /bin/bash # 進入容器
$ mongosh admin --username root --password mongo_root_pass # 登錄 admin 數據庫
$ use test_db # 創建/切換數據庫然而如果是在 CI(自動化部署)環境中,我們希望 MongoDB 啟動后自動創建需要的數據庫和用戶,而不是每次都要手動創建,這時應該怎么辦呢?
這時候要借助一個 Docker 下的特殊目錄:docker-entrypoint-init.d。
該目錄下可以自定義腳本文件,在容器第一次啟動時自動執行。mongo 鏡像可以識別該目錄下的 .sh 和 .js 文件,并按照順序執行。
那么我們就在 /docker/mongodb 目錄下創建一個 mongo-init.js 文件,并在運行容器時掛載:
-v /docker/mongodb/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js現在在該文件中編寫初始化邏輯,比如創建一個用戶:
// mongo-init.js
db.createUser({
user: 'test_user',
pwd: 'test_pass',
roles: [
{
role: 'dbOwner',
db: 'test_db',
},
],
});提示:docker-entrypoint-init.d 目錄下的腳本只會在第一次運行容器的時候執行。如果通過 -v 掛載過數據,那么就不是第一次。可以去掉 -v 模擬第一次運行。
上面的 JS 文件中可以訪問 db 對象,因為它在 mongosh 環境下執行。默認情況下,db 代表 “test” 數據庫。
如果我們要切換數據庫,命令是 use <db_name>。然而在 JS 文件中,顯然這種語法是不支持的。
關于如何在 JS 文件中切換數據庫,我找了很多方法,翻了一整天的文檔,終于找到了。
就是它:db.getSiblingDB(),等同于 use 命令。
因此,在 test_db 數據庫中創建/切換用戶,可以修改如下:
db = db.getSiblingDB('test_db');
db.createUser({
user: 'test_user',
pwd: 'test_pass',
roles: [
{
role: 'dbOwner',
db: 'test_db',
},
],
});通過 db.getSiblingDB() 方法,我們可以在 JS 腳本中創建多個數據庫和用戶。
如果你不想在 JS 代碼中創建/切換數據庫,更簡單的方法是,用環境變量 MONGO_INITDB_DATABASE 指定腳本在某個數據庫下執行。
Docker Compose 運行
如果你覺得運行容器的命令太長,那么使用 Docker Compose 也是一個不錯的選擇。
首先創建 compose.yml 配置文件如下:
version: '3.1'
services:
mongodb:
image: mongo:6
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: mongo_root_pass
MONGO_INITDB_DATABASE: test_db
volumes:
- '/docker/mongodb/data:/data/db'
- '/docker/mongodb/dump:/var/dump'
- '/docker/mongodb/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js'然后運行啟動命令:
$ docker compose up -d客戶端連接到 MongoDB
在啟動 MongoDB 時,傳入 --auth 參數表示開啟授權驗證,不傳則不開啟。
如果未開啟授權驗證,連接 MongoDB 不需要賬號密碼,連接 URL 如下:
mongodb://127.0.0.1:27017如果開啟授權驗證,則連接 URL 中必須指定數據庫、賬號、密碼,如下:
mongodb://user:pass@127.0.0.1:27017/dbname在《前端開發實戰派》的項目中使用 mongoose 連接數據庫,有了上面的 url 和用戶名密碼,連接方法如下:
const mongoose = require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/dbname', {
user: 'username',
pass: 'password',
}).then(() => {
console.log('數據庫連接成功:')
}).catch(err => {
console.log('數據庫連接失敗:', err)
})現在,你可以在我的開源項目 仿掘金博客系統 中添加自己的數據庫配置,項目就可以運行起來了。
總結
前面我們從 MongoDB 的安裝、運行配置、授權驗證等方面,全面介紹了如何用 Docker 將 MongoDB 運行起來,并在項目中連接使用。


























