挑战Docker的第二回
将MongoDB作为容器运行
使用Docker官方映像中的MongoDB映像作为容器来运行。
现在我们来创建卷。创建的卷分为一个用于存储MongoDB数据的卷和一个用于存储MongoDB配置的卷。
docker volume create mongodb
docker volume create mongodb_config
根据文件显示
卷是Docker容器用来生成和使用数据,并保持其持久性的机制。绑定挂载取决于主机操作系统的目录结构,而卷完全由Docker管理。
Mongo – 官方镜像|在DockerHub上也有说明。
数据存储位置 -> 警告(Windows和OS X)部分提到“为了在容器重新启动时保留数据,我们建议使用本地命名卷。”
对于音量,有以下的命令可用。
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"
}
]
确实有两个创建的卷。
创建网络
生成网络,使应用程序和数据库能够互相交互。
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表示与刚创建的卷进行关联。
加上–rm参数后,使用docker stop命令停止容器后,在docker ps -a中不再显示。这意味着自动删除容器。
–network表示连接到先前使用docker network create mongodb命令创建的(虚拟?)网络。如果省略此参数,将无法与其他容器进行通信。
– “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()
可能会在之后的代码中将数据库的URL指定给环境变量CONNECTIONSTRING。
重新构建图像
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フラグ用於設置環境變量。
在這裡將CONNECTIONSTRING設置為mongodb://mongodb:27017/notes。
MongoDB的URL格式看起来像是mongodb://[主机]:[端口]/[数据库名称],
因此右侧的mongodb部分应该对应着MongoDB创建的网络。
我试着发一篇帖子。
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”呢?但似乎是自动创建的。

如果放弃notes并再次进行POST,将会创建新的notes。MongoDB真是这么自由么…
IT旗的谜题
我不知道这个东西会带来什么效果。
我尝试将IT标志清除后重新启动MongoDB和Node.js容器,没有出现任何问题。我会将此作为我的任务。