版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.11.17 星期六 |
前言
Docker是一个跨平台的轻量级虚拟机,可移植性非常高,一次部署,终生可用。Docker可以在Linux、Windows、MacOS等平台上安装使用。接下来几篇我们就一起看一下Docker相关的内容。感兴趣的可以看下面几篇文章。
1. Docker应用详细解析(一) —— 在macOS上使用Docker(一)
Mounting Volumes: Sharing Host & Container Files
您经常希望在主机和容器之间共享文件或目录。 停止和删除容器时,数据库中的数据不应消失。 在不同版本的应用程序或运行相同数据库应用程序的不同容器之间共享数据库也很方便。 当您在容器中运行时,您可能希望将配置文件提供给数据库应用程序或将数据提供给机器学习应用程序。 您将在本节中学习如何执行这些操作。
1. Persisting Databases After the Container Exits - 容器退出后保留数据库
要将数据库存储在本地主机系统上,使其保持不变并且可以被其他容器访问,您将在启动CouchDB
容器时在Docker
的存储目录中创建一个卷。
在Docker run
终端窗口中,输入以下命令:
docker run --mount source=couchdbVolume,target=/opt/couchdb/data --network emoji-net -d --name couchdb couchdb
注意:在
--mount
值中,不要在=
符号周围或逗号后面添加空格。
第一次运行此命令时,它会在主机系统上的Docker存储目录中创建couchdbVolume
,然后将容器的/ opt / couchdb / data
目录的内容复制到couchdbVolume
中。 然后容器安装并使用couchdbVolume
来存储其数据库。
在您的EmojiJournalServer
终端窗口中,在同一网络上启动EmojiJournalServer
容器:
docker run --network emoji-net --name emojijournal -it -p 8090:8080 -v $PWD:/root/project -w /root/project emojijournal-run sh -c .build-ubuntu/release/EmojiJournalServer
刷新或打开localhost:8090 / client
,添加表情符号,然后 - 在Docker cleanup
终端窗口中 - 停止并删除两个容器:
docker rm $(docker stop $(docker ps -q))
即使您已删除创建它的CouchDB
容器,该卷仍然存在。 要查看此信息,请输入以下命令:
docker volume inspect couchdbVolume
输出如下:
[
{
"CreatedAt": "2018-10-26T08:00:59Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/couchdbVolume/_data",
"Name": "couchdbVolume",
"Options": null,
"Scope": "local"
}
]
使用Finder ▸ Go ▸ Go to Folder…
菜单项以查看mountpoint
目录......好吧,您可以尝试查看它 - 它不在那里! Docker的存储目录实际上存在于Docker引擎中并由其管理。 您不打算直接在主机文件系统上访问它。 您只能通过将其安装在Docker容器中来访问它。
现在,为了证明在删除CouchDB
容器后表情符号数据库仍然存在:在Docker run
终端窗口中重新运行CouchDB
命令,在EmojiJournalServer
终端窗口中运行EmojiJournalServer
命令,然后刷新localhost:8090 / client
- 这次,你不会丢失你的表情符号!
因为couchdbVolume
已经存在,所以CouchDB
容器刚刚安装它,将已经存储在那里的数据库暴露给EmojiJournalServer
容器,该容器找到并加载了由前一个EmojiJournalServer
容器创建的日志条目数据库。
Clean up
:停止并取出容器。 关闭浏览器窗口。 删除所有未使用的网络
docker network prune
2. Sharing a Database With Another Docker Container - 与另一个Docker容器共享数据库
您为在emoji-net
网络上运行的CouchDB创建了一个卷。 您已停止并删除了CouchDB容器,但卷仍然存在。 您可以将此卷重用于在默认网络上运行的CouchDB容器,从而有效地与另一个容器共享其数据库。
为了演示这一点,请将couchdbVolume
安装在默认桥接网络上运行的CouchDB容器中,以便主机上的EmojiJournalServer
可以访问已保存的日记条目数据库。
在默认桥接网络上启动CouchDB
容器,安装couchdbVolume
并发布其端口:
docker run --mount source=couchdbVolume,target=/opt/couchdb/data -p 5984:5984 -d --name couchdb couchdb
在您的EmojiJournalServer
终端窗口中,在主机系统上运行EmojiJournalServer
:
.build/debug/EmojiJournalServer
在您的主机系统上运行的EmojiJournalServer
在couchdbVolume
中查找并加载日记条目数据库,因此当您加载localhost:8080 / client
时,您会看到来自EmojiJournalServer
容器的表情符号:
在您的EmojiJournalServer
终端窗口中,按Control-C
停止此EmojiJournalServer
。 关闭浏览器窗口。
停止并删除CouchDB容器,然后输入此命令以删除所有未使用的卷:
docker volume prune
3. Providing Local Files to a Docker Container - 将本地文件提供给Docker容器
在容器中运行EmojiJournalServer
的命令具有-v $ PWD:/ root / project
选项,该选项将EmojiJournalServer
目录安装为容器中的/ root / project
。 本节演示对主机文件的更改会影响容器的文件,反之亦然。
在您的EmojiJournalServer
终端窗口中,在后台启动EmojiJournalServer
容器:
docker run --name emojijournal -itd -p 8090:8080 -v $PWD:/root/project -w /root/project emojijournal-run sh -c .build-ubuntu/release/EmojiJournalServer
然后输入以下命令:
docker exec -it emojijournal bash
此命令创建运行bash
Unix shell的交互式终端会话。 你得到一个以〜/ project#
结尾的命令行提示符。 在此提示符下,输入此命令以查看容器的project
目录:
ls -l
输出列出与Finder中的EmojiJournalServer
文件夹相同的文件:
使用您喜欢的文本编辑器在此文件夹中创建一个新文件 - 例如,包含文本I was here
的kilroy.txt
。在〜/ project#
提示符下,再次输入ls -l
,以查看您的新文件容器。 在〜/ project#
提示符下输入以下命令:
rm kilroy.txt
在Finder中,文件消失。 这就是将本地目录连接到容器是多么容易 - 一个地方的变化会影响另一个!
Cleanup:停止并移除容器。
4. Choosing Between Volume & Bind Mount
您现在已经看到了两种在容器中挂载主机目录的方法:couchdbVolume
是一个volume
,而EmojiJournalServer
目录是一个bind mount
。卷和绑定装载之间的主要区别在于它位于主机文件系统上,以及是否可以通过主机文件系统直接访问它。
您将本地系统上的特定路径(如EmojiJournalServer
文件夹)bind-mount
到容器中的特定路径- / root / project
。您可以直接与本地目录进行交互,更改将显示在容器中。同样,容器所做的更改也会显示在Finder中。
您可以通过在docker run
或docker volume create
命令中指定名称(如couchdbVolume
)来创建volume
。该卷位于Docker的存储目录中,位于本地系统的Docker引擎中。您无法直接与此目录的内容进行交互。您可以将其安装到容器中,然后可以检查其元数据或将其删除。 Docker管理卷中的读写文件。
另一个很大的区别是当您公开现有容器目录时会发生什么。
如果将本地目录绑定到现有容器目录,则本地目录中的内容会模糊容器目录的内容 - 如果将本地couchdb-config
目录绑定到CouchDB容器的local.d
目录,则会发生这种情况。您有效地覆盖容器目录。别担心,原始目录仍然是只读镜像!
如果将容器目录公开为volume
,则会将其内容复制到主机上的卷中。当您使用CouchDB
容器的/ opt / couchdb / data
目录作为目标创建couchdbVolume
时,会发生这种情况。
5. --mount or --volume?
您还可以使用两个不同的选项来装入卷或绑定装载本地目录。 他们做同样的事情 - 他们只是使用不同的语法。
--mount
选项比--volume
更新。 它使用逗号分隔的key=value
对,键的顺序无关紧要。 此选项没有速记版本。
--volume
标志,简写-v
,有三个冒号分隔的字段:顺序很重要,但你必须记住或查找每个字段的含义。
Docker文档建议使用--mount
选项而不是-v
选项:它更详细,但这使得理解和记忆更容易。
以下两个命令是等效的 - 它们将当前本地目录bind-mount
安装到容器中的新/ home
目录:
docker run --mount type=bind,source=/`pwd`,target=/home ibmcom/kitura-ubuntu
docker run -v $PWD:/home ibmcom/kitura-ubuntu
以下两个命令是等效的 - 它们在Docker
的存储目录中创建一个卷:
docker run --mount source=KituraVolume,target=/Kitura-Starter ibmcom/kitura-ubuntu
注意:
type=volume
是默认的。
docker run -v KituraVolume:/Kitura-Starter ibmcom/kitura-ubuntu
注意:
-v
选项的第一个字段是名称,而不是路径,因此Docker
创建卷,而不是bind mount.
。
两个命令都将/ Kitura-Starter
的内容复制到名为KituraVolume
的卷中。 然后Kitura
容器安装并使用KituraVolume
。 您可以将KituraVolume
安装在其他容器中,以便他们访问其内容。
您可以指定read-only
访问权限:
docker run --mount source=KituraVolume,target=/Kitura-Starter,readonly --name kitura ibmcom/kitura-ubuntu
docker run -v KituraVolume:/Kitura-Starter:ro --name kitura ibmcom/kitura-ubuntu
这是来自Docker
文档的--mount
和--volume
的行为之间的另一个区别:
- 如果使用
-v
或--volume
绑定安装Docker主机上尚不存在的文件或目录,则-v
会为您创建端点。 它始终作为目录创建。 - 如果使用
--mount
绑定安装Docker
主机上尚不存在的文件或目录,则Docker
不会自动为您创建它,但会生成错误。
请注意,如果使用-v
将主机上不存在的目录绑定安装到容器中存在的目录,则会将其创建为主机上的空目录,因此其空白会遮盖原始目录容器中的内容。 例如,如果您尝试使用-v $ PWD / kitura-dir:Kitura-Starter
将Kitura-Starter
目录从容器复制到本地文件系统,那么您所获得的只是文件系统中的空目录容器。
6. Copying Files Between Host & Container - 在主机和容器之间复制文件
如果您只想将正在运行的Docker
容器中的文件或目录保存到本地系统,则可以复制它:
docker cp kitura:/Kitura-Starter .
您还可以将文件或目录从本地系统复制到容器:
docker cp kilroy.txt kitura:/var/tmp
Summary of Docker Commands - Docker命令总结
你在本教程中看到了很多Docker命令! 以下是它们的列表。 方括号中的术语(如[image]
)是特定名称或ID的占位符。
docker run
命令:
docker run [options] [image] [command for -it options]
您在本教程中使用的docker run
选项:
- --detach / -d
- --env / -e [ENV_VAR=value]
- --interactive --tty / -it ... [command]
- --name [name]
- --network [network]
- --mount source=[volume],target=[container-dir]
- --publish / -p [host port]:[container port]
- --volume / -v [host-dir]:[container-dir]
您在本教程中使用的其他Docker命令(加上一两个您没见过的相关命令):
- docker pull [image]
- docker images or docker image ls
- docker ps -a or docker container ls -a
- docker ps -a -q -f [filter condition]
- docker exec -it [container] bash
- docker stop [container]
- docker start [container]
- docker rm $(docker ps -a -q -f status=exited)
- docker rm $(docker stop $(docker ps -q))
- docker rm [container IDs or names]
- docker rmi [image] or docker image rm [image]
- docker container inspect [container]
- docker network create [network-name]
- docker network inspect [network-name]
- docker network ls
- docker network prune
- docker volume create [volume-name]
- docker volume inspect [volume-name]
- docker volume ls
- docker volume prune
- docker cp [container:container-path] [host-path]
- docker cp [host-path] [container:container-path]
一些有用的方法来分离在前台运行的容器:
-
Control-P-Q
在不停止容器的情况下分离 - 如果容器位于前台,因为您运行了
docker run -it ... bash
,则在bash
shell提示符处退出会停止容器。 - 如果容器位于前台,因为您运行了
docker exec -it ... bash
,则exit
bash shell提示符退出bash shell
但不会停止容器。
本教程向您介绍了Docker的一小部分功能和可能性。 它没有涉及创建自己的Docker
镜像,组成Docker服务,使用Docker for CI / CD
,集群和使用Docker Swarm调度容器等等。 希望本教程为您探索Docker世界提供了坚实的基础。 以下是一些可以帮助您的资源:
- Docker’s documentation非常全面且非常有用。
- 你可以在网上找到很多
Docker cheat sheets
,比如github.com/wsargent/docker-cheat-sheet和devhints.io/docker。 - Awesome Docker是Docker资源和项目的精选列表。
后记
本篇主要讲述了在macOS上使用Docker,感兴趣的给个赞或者关注~~~