Docker应用详细解析(一) —— 在macOS上使用Docker(一)

栏目: 编程工具 · 发布时间: 6年前

内容简介:Docker是一个跨平台的轻量级虚拟机,可移植性非常高,一次部署,终生可用。Docker可以在Linux、Windows、MacOS等平台上安装使用。接下来几篇我们就一起看一下Docker相关的内容。Docker是一种工具,可以轻松地在容器中运行应用程序。 容器提供隔离和安全性,如虚拟机,但它们要小得多,因为它们在主机系统中运行。作为iOS开发人员,您为什么要使用Docker? 避免版本问题 - 运行操作系统版本,编程语言,数据库应用程序,Web应用程序和Web服务器,机器学习程序 - 所有这些都在隔离的

版本记录

版本号 时间
V1.0 2018.11.17 星期六

前言

Docker是一个跨平台的轻量级虚拟机,可移植性非常高,一次部署,终生可用。Docker可以在 Linux 、Windows、MacOS等平台上安装使用。接下来几篇我们就一起看一下 Docker 相关的内容。

开始

Docker是一种工具,可以轻松地在容器中运行应用程序。 容器提供隔离和安全性,如虚拟机,但它们要小得多,因为它们在主机系统中运行。

作为iOS开发人员,您为什么要使用Docker? 避免版本问题 - 运行操作系统版本,编程语言,数据库应用程序,Web应用程序和Web服务器,机器学习程序 - 所有这些都在隔离的环境中,以避免Mac上安装的任何其他副作用。

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

在本教程中,您将熟悉Docker词汇表和用于创建,检查和删除容器,网络和数据卷的命令。 您将学习如何在后台或前台运行Docker容器,并在两者之间切换;如何发布端口;如何连接数据库应用程序和在不同容器中运行的Web应用程序;以及如何在容器和Mac之间以及容器之间共享目录。 完成本教程后,您将很快使用 Docker ninjadom

注意:这个Docker教程假设您愿意在终端中输入 Unix 命令。 熟悉Unix命令和文件路径,数据库应用程序和 localhost 端口会很有帮助。

1. Installing Docker - 安装Docker

Docker最初是为 Linux 开发的。 在 macOS 上运行Docker曾经相当复杂,但是2016年7月推出了原生macOS应用程序 Docker for Mac ,所以现在它变得轻而易举!

通用版 Community Edition (CE) 是免费下载的,所以 download Docker CE for Mac ,然后安装并运行该应用程序。 Moby the Whale 应出现在Mac的状态栏中:

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

注意:如果上面的直接下载链接不起作用,请转到 Docker’s web page ,单击 Please Login to Download 按钮,创建一个帐户,然后等待激活电子邮件。 在您等待的同时,使用在线 Play-With-Docker playground

Docker Terminology & Housekeeping

在本节中,您将学习一些Docker词汇表,并熟悉使用Unix命令行进行基本的 housekeeping 任务。

注意:本教程中有一个方便的所有命令列表 - 向下滚动到最后。

1. Hello World

打开终端,然后输入此命令以查看Docker是否正常运行:

docker run hello-world

workhorse Docker 命令是 docker run ,这是最简单的 docker run 命令 - 它指定要运行的Docker镜像。 如果映像不在主机系统上,它会尝试从默认的Docker映像注册表中提取映像。 单词image的含义类似于您下载为 .dmg 文件的磁盘映像。 Docker镜像是一个应用程序,您可以在你的系统Docker容器中上运行它。

这个命令的输出解释了Docker刚刚做了什么:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete 
Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

哇,要学习很多新术语! 从顶部开始:

  • 虽然你只要求了hello-world,但是Docker寻找了 hello-world:latest - latest 是一个指示版本的标签。 如果您没有要求特定版本,Docker假定您需要最新版本。
  • 由于映像不在您的系统上,因此Docker将其从 library/hello-world 中拉取 - 它位于默认映像注册表 Docker Hub 中。 您将在 Running a Web App 部分中访问此位置。
  • Docker clientDocker daemonDocker Engine 的一部分,它是现在在Mac上运行的客户端 - 服务器应用程序。 daemon 是服务器,客户端是docker命令行界面 (CLI) 。 客户端使用引擎的 REST APIdaemon 发出指令。
Docker应用详细解析(一) —— 在macOS上使用Docker(一)

Docker engine (image from docs.docker.com)

注意:您将在本教程后面了解Docker的网络和数据量功能。

Docker镜像有很多种类型:

  • OS - 操作系统 :主要是 Linux 风格,如 Ubuntu,Alpine 等。
  • programming languages - 编程语言Swift,Ruby,PHP,Haskell,Python,Java,Golang 等。
  • databases - 数据库MySQL,CouchDB,PostgreSQL,Oracle,IBM Db2 等。
  • application frameworks - 应用程序框架Node.js,Flask,Kitura,Tomcat 等。
  • Web服务器Nginx,Apache 等。
  • 用于机器学习的Web应用程序 ,包括 Python 应用程序和Jupyter笔记本

Docker镜像由 layers 组成 - 较高层(API或应用程序)使用较低层(OS或编程语言)。运行镜像会创建一个容器 - 一个位于镜像只读层顶部的精简读写层。您可以使用非常少的内存在多个容器中运行相同的映像。每个容器只是读写层,系统上只存在一个映像副本。镜像的顶部只读层指定要在容器中运行的命令 - 对于 hello-world ,此命令只输出 Hello from Docker! 信息。

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

Container layer on top of image layers (image from docs.docker.com)

2. Using Docker Commands - 使用Docker命令

现在到 housekeeping 部分 - 您需要跟踪Docker在您的系统上创建的内容,以便您可以在不再需要时删除内容。

首先,一些关于Docker命令行界面 (CLI) 语法的一般信息:Docker命令类似于Unix命令,但它们以“docker”开头,如 docker run,docker image,docker container,docker network

大多数命令有几个 options ,许多选项都有简写版本。选项的全名是 --something ,有两个破折号,如 --name--publish 。简写版本是 -abbrev ,带有一个破折号,例如 -p 用于 --publish-v 用于 --volume 。一些选项,如 --name ,没有简写版本。

大多数选项都需要值,例如 -p 8080:8080--name kitura 。少数没有值,可以一起运行,比如 -it-ti ,简称 --interactive --tty 。您必须在选项名称后面指定选项的值,但选项和选项 - 值对可以按任何顺序出现。

许多选项值将 host machine 上的某些内容映射到容器中的某些内容。在您的情况下,主机是您的Mac。

您将在本教程中使用所有这些以及更多内容。

首先在终端窗口中输入以下命令:

docker images

输出列出了系统上的Docker镜像,特别是 hello-world:Docker 提取的最新图像:

REPOSITORY    TAG     IMAGE ID      CREATED       SIZE
hello-world   latest  e38bc07ac18e  2 months ago  1.85kB

注意:您的输出将显示不同的 IMAGE IDCREATED 值。

正如 docker run hello-world 的输出所示, Docker daemon 从该映像创建了一个容器,以运行生成输出的可执行文件。

运行此命令以显示系统上的所有 (-a) Docker容器:

docker ps -a

注意:这与 docker container ls -a 的功能相同。 对于这两个命令,不使用 -a 选项仅列出正在运行的容器。

输出只显示一个容器:

CONTAINER ID  IMAGE        COMMAND   CREATED    STATUS  PORTS  NAMES
4ed31ad50912  hello-world  "/hello"  16 sec...  Exited ...     stupefied_gates

Docker为容器创建了一个ID和一个名称 - 您的值将不同。 虽然容器已退出,但它仍在您的系统上。

运行 hello-world ,然后再次显示所有容器:

docker run hello-world
docker ps -a

注意:使用 Up ArrowDown Arrow 键浏览您在此终端窗口中运行的 Unix 命令。

现在有第二个容器,具有不同的ID和名称值:

CONTAINER ID  IMAGE        ...  NAMES
4ed31ad50912  hello-world  ...  stupefied_gates
e5d3669f5ca1  hello-world  ...  flamboyant_zhukovsky

您可以通过指定容器的名称或ID或其ID的前3个字符来删除容器,并且可以在单个命令中删除多个容器,如下所示(您的ID和名称将不同):

docker rm e5d stupefied_gates

输出只是回显容器ID或名称。 确认容器已消失:

docker ps -a

看到 Docker 提供的名称很有趣,但是当你使用容器一段时间之后,可以方便地为容器提供自己的名字。 输入以下命令:

docker run --name helloWorld hello-world

然后列出容器:

docker ps -a

你已经命名了你的容器:

CONTAINER ID  IMAGE        ...  NAMES
c5f411a593a3  hello-world  ...  helloWorld

再次运行相同的命令:

docker run --name helloWorld hello-world

现在您收到一条错误消息,因为该容器名称已被使用:

docker: Error response from daemon: Conflict. The container name "/helloWorld" 
  is already in use by container 
"c5f411a593a341593ff531c444c44f7dd7fd3f1a006395c9c3cbf5ff687838e1". You have to 
  remove (or rename) that container to be able to reuse that name.

接下来,我想向你展示一个很酷的 housekeeping 技巧,所以运行几次 docker run hello-world ,以获得混乱你的系统的容器。 然后运行此命令列出它们:

docker ps -a -q -f status=exited

这是您用来显示系统上所有Docker容器的 docker ps -a 命令,以及两个选项。 选项 -q--quiet 的缩写,因此该命令仅显示数字ID。 选项 -f--filter 的缩写,过滤条件是 status = exited 。 所以输出看起来像这样(你的ID会有所不同):

d8d962602abf
64b2eb1af5da
5fde263a26a0
1659b24f2ce2
ff5e7f6a17b5
ab4bf3b4c32b
0d0e48dfcf32
18d8beb2fe60
c5f411a593a3

现在,不要将每个ID复制粘贴到 docker rm 命令中,只需将此输出提供给 docker rm 命令:

docker rm $(docker ps -a -q -f status=exited)

这个命令首先运行 $() 中的部分,以获取已激活容器的ID列表,然后将它们全部删除 - 非常棒!

既然已经删除了容器,您也可以删除镜像:

docker rmi hello-world

您的输出看起来类似于:

Untagged: hello-world:latest
Untagged: hello-world@sha256:f5233545e43561214ca4891fd1157e1c3c563316ed8e237750d
59bde73361e77
Deleted: sha256:e38bc07ac18ee64e6d59cf2eafcdddf9cec2364dfe129fe0af75f1b0194e0c96
Deleted: sha256:2b8cbd0846c5aeaa7265323e7cf085779eaf244ccbdd982c4931aef9be0d2faf

再次检查镜像

docker images

你的系统现在是干净的了

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

节省时间提示 - Docker清理终端窗口:将此终端窗口移动到桌面的一角,并仅将其用于运行Docker清理命令。 这样,你想要的命令只会是几个向上箭头击键。 另一个技巧是输入Unix命令 history 以查找所需命令的编号,然后输入 再次运行该命令。 例如,下面是我历史记录中的最后几个命令,因此输入命令 !18 将删除所有 exited 的容器。

15  docker run --name helloWorld hello-world
16  docker ps -a
17  docker ps -a -q -f status=exited
18  docker rm $(docker ps -a -q -f status=exited)
19  docker rmi hello-world
20  docker images
21  history

Running a Web App in a Docker Container - 在Docker Container中运行一个Web App

许多iOS应用程序与Web服务器通信,Web服务器也是Web应用程序的后端。 而且您经常希望与iOS应用程序的交互反映在Web应用程序中,反之亦然。 您可以在没有容器的情况下在本地运行Web应用程序,但在容器中运行它可以更容易地单独测试不同的配置,或者测试具有不同权限的用户类型。

要在容器中运行Web应用程序,首先需要了解的是如何在浏览器的 localhost 中访问容器的端口。 Docker术语是发布端口 (publishing ports) 。 在本节中,您将了解发布端口,并快速查看默认的Docker镜像注册表 Docker Hub

1. Publishing Ports

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

实际上,你不需要人工智能来找出端口! 语法是 --publish 后跟两个端口号,用冒号分隔。 诀窍是记住第一个值是主机在这里,第二个值是容器那里 - 你从那里发布一个端口。 对于第一个号码 - 主机的端口 - 您可以指定任何您喜欢的号码,但最简单的选择是使用与容器端口相同的号码。 对于第二个数字,您会遇到容器暴露的任何内容 - 如果您尝试更改它,则会出现错误。 将容器的端口发布到不同的 localhost 端口的能力使得同时运行多个Web应用程序容器变得容易。

IBM Kitura 的一个非常简单的Web应用程序开始。 在浏览器中,在 Docker Hub 上加载Docker镜像的默认注册表。 在Search框中输入 kitura ,然后选择第一个返回的项目:

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

打开一个新的终端窗口 - 这将是您的 Docker run 终端窗口。 有时,您将在此窗口中的前台运行一个进程,因此您将无法在其中运行任何内务处理命令。 这就是你的 Docker cleanup 窗口会派上用场的地方!

单击 Docker Pull Commandcopy icon ,并将其粘贴到 Docker run 终端窗口中:

docker pull ibmcom/kitura-ubuntu

ibmcom / kitura-ubuntu 映像将一个简单的Web应用程序层叠到 Kitura 应用程序框架上,该框架分层到 swift-ubuntu 映像上,这是在 Ubuntu 操作系统之上分层的Swift编程语言。 UbuntuLinux 的一个版本。

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

镜像的 Docker Hub 页面没有给出任何特定的运行指令,所以请继续尝试:

docker run ibmcom/kitura-ubuntu

注意:您可以刚刚输入命令 docker run ibmcom / kitura-ubuntu 而不是 pull 命令,它会在运行之前从 Docker Hub 中提取镜像。 但有时,您可能只想下载镜像,然后稍后运行 - 也许在设置其他组件之后。

容器启动,包含以下消息:

[2018-10-02T21:53:57.690Z] [WARNING] [ConfigurationManager.swift:261 load(url:
  deserializerName:)] Unable to load data from URL 
  /Kitura-Starter/config/mappings.json
[2018-10-02T21:53:57.698Z] [INFO] [main.swift:28 Kitura_Starter] Server will be 
  started on 'http://localhost:8080'.
[2018-10-02T21:53:57.703Z] [INFO] [HTTPServer.swift:124 listen(on:)] Listening 
  on port 8080

注意:您还可以在 docker ps 输出的 PORTS 列中查看容器的端口。

它尝试但未能从JSON文件加载数据,然后开始侦听 localhost:8080 。 请注意,您没有收到 Unix shell 提示符 - 此进程正在前台运行,并且尚未退出。

localhost:8080 打开浏览器 - 不,“Can’t Connect to the Server”。 发生了什么? 容器在其自己的环境中公开端口8080,但您必须将此端口发布到主机系统上的端口,以查看其中的内容。

首先,摆脱这个试用版容器:在你的 Docker cleanup 窗口中,运行一个命令来查找容器的ID,停止容器,然后将其删除。 因为只有一个容器在运行,所以您可以使用一个带有两个 $() 嵌套级别的命令来停止并删除所有正在运行的容器。 在检查下面的解决方案之前,请尝试自己解决此问题。

docker rm Docker应用详细解析(一) —— 在macOS上使用Docker(一) (docker ps -q))

此命令停止并删除所有正在运行的容器。 如果您有要继续运行的运行容器,请使用 docker ps 自行查找要停止和删除的正在运行的容器的ID。

返回 Docker run 终端窗口 - 返回 Unix shell 提示符。 输入以下命令:

docker run -p 80:8080 --name kitura -d ibmcom/kitura-ubuntu

-p 选项 - --publish 的缩写,将真正本地的l ocalhost:80 映射到容器的 8080 端口。 --name 选项指定容器名称。 -d 选项 --detach 的缩写,在后台运行容器进程,因此您可以立即返回 Unix shell 提示符。

在浏览器中,打开 localhost:80 以查看此欢迎页面:

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

在另一个端口上运行第二个容器:

docker run -p 90:8080 --rm --name kitura2 ibmcom/kitura-ubuntu

在浏览器中,打开 localhost:90 以查看相同的欢迎页面。

这次,容器在前台运行 - 你没有使用 -d 选项,所以你没有得到 Unix shell 提示符。 此外, -- rm 选项表示在停止容器时将删除容器。

Docker cleanup 窗口中,输入以下命令:

docker stop kitura2

它可能需要几秒钟才能回复 kitura2 ,并且 Unix shell 提示符会在 Docker run 窗口中返回。

使用 docker ps -a 查看没有 Exited 容器:

CONTAINER ID  IMAGE                .. STATUS       PORTS                  NAMES
f64f7eb69258  ibmcom/kitura-ubuntu .. Up 47 sec..  0.0.0.0:80->8080/tcp   kitura

第一个容器仍在后台运行,因此请输入此命令以停止它:

docker stop kitura

Unix shell 提示符返回时,请刷新 localhost:80 页面 - 它将不会加载,因为您停止了容器进程。

使用 docker ps -a 检查第一个容器是否仍然存在,然后运行此命令重新启动它:

docker start kitura

刷新 localhost:80 页 - 这次它有效!

Clean up:关闭浏览器窗口。 停止并取出容器。 请注意,除非使用 force ,否则无法删除正在运行的容器。

Running a Web App With a Database - 运行使用数据库的Web App

在本节中,您将首先在容器中运行数据库应用程序,由主机系统上运行的Web应用程序访问。 您需要发布数据库应用程序的端口,以便Web应用程序可以访问它。

如果要在多个端口上运行Web应用程序,如果它在容器中运行也会更容易。 但是您必须做一些额外的工作才能让Web应用程序访问数据库应用程序。

1. Running CouchDB in a Docker Container - 在Docker容器中运行CouchDB

Web应用程序通常将数据存储在数据库应用程序中,如 PostgreSQLCouchDB 。 在 Docker 容器中运行数据库应用程序可以避免版本问题或测试不同的版本或用户类型。

Docker run 窗口中,输入此命令以在Docker容器中运行 CouchDB

docker run --name couchdb -p 5984:5984 -d couchdb

CouchDB 镜像始终公开端口 5984 。您可以将其发布到本地主机端口号,以便Web服务器应用程序可以访问它。

注意:要在容器中运行 CouchDB 时指定用户和密码信息,请使用 --env(-e) 选项 - 例如:

docker run -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password --name couchdb -p 5984:5984 -d couchdb

在等待 CouchDB 时,构建一个使用它的Web服务器应用程序。 别担心 - 这只是几个 Unix 命令!

打开另一个终端窗口 - 您将在此处输入必须在 EmojiJournalServer 目录中运行的命令。 在 Finder 中,找到下载材料中的 EmojiJournalServer 文件夹,然后在终端窗口中运行以下命令:

cd <drag the EmojiJournalServer folder from Finder to the terminal window>
swift build 
.build/debug/EmojiJournalServer

注意:随着应用构建,您将收到一些弃用警告。 别理他们。

首先,您切换到 EmojiJournalServer 目录,该目录包含 Package.swift 文件。 第二个命令使用此文件构建Web服务器应用程序,第三个命令运行它。 输出如下:

[2018-10-22T14:56:58.919+11:00] [INFO] [Application.swift:45 
  connectionProperties] Running on MacOS - using local database
[2018-10-22T14:56:58.932+11:00] [WARNING] [ConnectionProperties.swift:57 
  init(host:port:secured:username:password:)] Initializing a CouchDB connection 
  without a username or password.
[2018-10-22T14:56:59.018+11:00] [INFO] [Application.swift:94 createNewDatabase()] 
  Database does not exist - creating new database
[2018-10-22T14:56:59.112+11:00] [INFO] [EntryRoutes.swift:43 
  initializeEntryRoutes(app:)] Journal entry routes created
[Mon Oct 22 14:56:59 2018] com.ibm.diagnostics.healthcenter.loader INFO: Swift 
  Application Metrics
[2018-10-22T14:56:59.206+11:00] [INFO] [Metrics.swift:47 
  initializeMetrics(app:)] Initialized metrics.
[2018-10-22T14:56:59.208+11:00] [INFO] [WebClientRoutes.swift:43 
  initializeWebClientRoutes(app:)] Web client routes created
[2018-10-22T14:56:59.218+11:00] [INFO] [HTTPServer.swift:124 listen(on:)] 
  Listening on port 8080

输出的最后一行表示它是 “listening on port 8080” ,因此在浏览器中打开 localhost:8080 以查看 Kitura 欢迎页面。

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

Journal entry routeclient ,因此将 / client 添加到位置URL以查看 Emoji Journal 应用程序:

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

单击笑脸以打开表情符号菜单。 选择一个表情符号,然后单击大+号。 这会将您选择的表情符号添加到日记中:

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

注意: EmojiJournalServer 是我们的 Server Side Swift with Kitura 的示例Web服务器应用程序。 我编辑了一下,所以它在Docker容器中工作。

此Web服务器应用程序正在您的主机系统上运行,而不是在Docker容器中运行。 要同时运行另一台服务器,您必须编辑和重建Xcode项目以公开不同的端口,或者在Docker容器中运行服务器。 这是一个Docker教程,所以当然,你要做的第二件事!

EmojiJournalServer 终端窗口中的 Control-C ,停止服务器。

2. Running CouchDB & Server in Docker Containers - 在Docker容器中运行CouchDB和Server

EmojiJournalServer 文件夹还包含 DockerfileDockerfile-toolsrunDocker.sh 文件。

EmojiJournalServer 终端窗口中输入以下命令:

cat Dockerfile
cat runDocker.sh

你只是看着 DockerfilerunDocker.shDockerfile-tools 看起来类似于 Dockerfile 。 这些文件包含构建运行 EmojiJournalServer 所需的Docker镜像的说明。 runDocker.sh shell脚本包含构建这些镜像并运行应用程序的命令。

输入此命令以运行 shell 脚本 - 确保在 runDocker.sh 之前键入点和空格:

. runDocker.sh

这需要一段时间 - 去喝点东西......,你最终会得到这样的东西:

[2018-10-24T05:25:20.387Z] [INFO] [Application.swift:50 connectionProperties] 
  No cloud credentials - running in Docker
[2018-10-24T05:25:20.390Z] [WARNING] [ConnectionProperties.swift:57 
  init(host:port:secured:username:password:)] Initializing a CouchDB connection 
  without a username or password.
[2018-10-24T05:25:20.432Z] [ERROR] [ClientRequest.swift:344 end(close:)] 
  ClientRequest Error, Failed to invoke HTTP request. CURL Return 
  code=CURLcode(rawValue: 6)
[2018-10-24T05:25:20.432Z] [INFO] [Application.swift:98 createNewDatabase()] 
  Database does not exist - creating new database
[2018-10-24T05:25:20.445Z] [ERROR] [ClientRequest.swift:344 end(close:)] 
  ClientRequest Error, Failed to invoke HTTP request. CURL Return 
  code=CURLcode(rawValue: 6)
[2018-10-24T05:25:20.446Z] [ERROR] [Application.swift:104 createNewDatabase()] 
  Could not create new database: (Optional("Internal Error")) - journal 
  entry routes not created
[2018-10-24T05:25:20.451Z] [INFO] [HTTPServer.swift:124 listen(on:)] 
  Listening on port 8080

此输出类似于您从 .build / debug / EmojiJournalServer 命令获得的输出,但 Database does not exist 似乎错误 - 为什么它不会看到您已创建的数据库? 它变得更糟, “Could not create new database”“journal entry routes not created”

runDocker.sh 中的最后一个命令发布了 80808090 ,因此在浏览器中刷新或打开 localhost:8090 :Kitura欢迎页面就在那里。 但是 localhost:8090 / client 不是:

Cannot GET /client.

发生了什么? 两个容器都在默认桥接网络上运行。 在 Docker run 终端窗口中,输入以下命令进行检查:

docker network inspect bridge

输出列出了有关 emojijournalcouchdb 容器的信息:

"Containers": {
    "029114b903dd55ad4cce2160bd0c956439e939a8f6cfb81bb9a5f400ef953727": {
        "Name": "emojijournal",
        "EndpointID": "32ed8052f7e598b9fd027f5a227d5b277b53d66237b44018648e79dc22125c8c",
        "MacAddress": "02:42:ac:11:00:03",
        "IPv4Address": "172.17.0.3/16",
        "IPv6Address": ""
    },
    "2aaecbcb834ae405f4a5046f5195c1b2026b4122d1d05401b87fc6442085acf0": {
        "Name": "couchdb",
        "EndpointID": "043c1ec8eb3521caad9ec8ebacea2bf0a876e1c21cbfe3144f04be63ed3d9986",
        "MacAddress": "02:42:ac:11:00:02",
        "IPv4Address": "172.17.0.2/16",
        "IPv6Address": ""
    }
}

我输出的 couchdb 的IP地址是 172.17.0.2 ,但在Mac上或下次运行 CouchDB 时可能会有所不同。 您可以编辑和重建Web应用程序以访问CouchDB的 5984 端口 172.17.0.2 ,但运行时IP地址可能会有所不同。 理想情况下,您希望Web应用程序从主机名 couchdb 自动发现 CouchDB 的IP地址,无论它是什么时候。

诀窍是创建用户定义的桥接网络,然后将两个容器连接到此网络。 然后每个容器可以使用另一个主机名来访问其端口。 另一个好处是网络外的实体无法访问这些端口。

Docker cleanup 终端窗口中,输入此命令以停止和删除两个容器:

docker rm $(docker stop $(docker ps -q))

回到 EmojiJournalServer 终端窗口,运行以下命令:

docker network create emoji-net

您已经创建了一个名为 emoji-netDocker 网络。

docker run --network emoji-net -d --name couchdb couchdb

您已在此网络上启动了 CouchDB 容器。 您不需要为 CouchDB 发布本地端口 - Web应用程序将在同一网络上运行,因此它将能够看到CouchDB向网络公开的端口。

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

现在你已经在这个网络上启动了一个 EmojiJournalServer 容器。 此命令与 runDocker.sh 中的最后一个命令相同,并添加了 network 选项。 检查此命令的其余部分:

  • --name emojijournal 命名容器
  • -it ... sh -c .build-ubuntu / release / EmojiJournalServer 创建一个交互式终端,并执行shell命令来运行 EmojiJournalServer
  • -p 8090:8080 将容器的8080端口发布到 localhost:8090
  • -v $ PWD:/ root / project 将当前目录作为 / root / project 挂载到容器中 - 它将当前目录绑定到容器内的 / root / project ,因此对主机文件的更改会影响容器的文件,反之亦然。 Mounting Volumes 在本教程后面有自己的部分。
  • -w / root / project 将容器的工作目录设置为 / root / project-w--workdir 的缩写。

这次,它成功创建了一个新的数据库和日记帐分录路径:

...
[2018-10-25T22:53:32.642Z] [INFO] [Application.swift:98 createNewDatabase()] 
  Database does not exist - creating new database
[2018-10-25T22:53:32.702Z] [INFO] [EntryRoutes.swift:43 
  initializeEntryRoutes(app:)] Journal entry routes created
...

注意:某些 Docker Hub 映像的说明会告诉您使用 --link 来连接容器。 Docker 文档称它是“最终可能被删除的遗留功能”,您应该使用用户定义的网络和 --network

服务器在前台运行 - 按 Control-P-Q 分离此过程而不停止它。 Unix shell 提示符返回。

输入此命令以检查您的网络:

docker network inspect emoji-net

向下滚动以查看 Containers 中列出的 emojijournalcouchdb

"Containers": {
    "5fb6ef216c90489fec958c860915760f8d9b801800c6d0f8a70c9c8304c128d5": {
        "Name": "emojijournal",
        "EndpointID": "95871482d549441b22de602e5d27de21912cb85977c1ba4f5b74f5cb2fdc6fb6",
        "MacAddress": "02:42:ac:14:00:03",
        "IPv4Address": "172.20.0.3/16",
        "IPv6Address": ""
    },
    "686f1e8b59f1d95d482991bbc38e85d14bf1fd22bc7b87148f65fc899e834f2a": {
        "Name": "couchdb",
        "EndpointID": "1d7c116dae6d9039329de2db788cb27429330519257c24a5ec4fcac0764ab426",
        "MacAddress": "02:42:ac:14:00:02",
        "IPv4Address": "172.20.0.2/16",
        "IPv6Address": ""
    }

注意: CouchDB 容器必须命名为 “couchdb” ,因为这是 EmojiJournalServer 所期望的。 它在 Application.swift 中被硬编码为 App 类的 connectionProperties 属性中的主机名。

在浏览器中,刷新或打开 localhost:8090 / client 并添加表情符号或三个表情符号。 然后在 EmojiJournalServer 终端窗口中输入此命令 - 请注意,名称为 emojijournal2 ,发布的端口号为 8070

docker run --network emoji-net --name emojijournal2 -it -p 8070:8080 -v $PWD:/root/project -w /root/project emojijournal-run sh -c .build-ubuntu/release/EmojiJournalServer

这个新的 emojijournal2 容器找到由第一个 EmojiJournalServer 创建的 CouchDB 数据库:

[2018-10-25T23:38:14.632Z] [INFO] [Application.swift:80 postInit()] Journal 
  entries database located - loading...

在浏览器中打开 localhost:8070 / client - 它显示您在端口 8090 上添加的相同表情符号。在端口 8070 上添加另一个表情符号,然后刷新端口 8090 以查看它。

Docker应用详细解析(一) —— 在macOS上使用Docker(一)

3. Where’s My Database?

回想一下您在默认桥接网络上运行的 CouchDB 容器 - 您向其添加了表情符号。 然后你停下来并将其删除,然后在 emoji-net 网络上创建了另一个 CouchDB 容器。 在此网络上启动 EmojiJournalServer 创建了一个新的空日记帐分录数据库。 然后在同一网络上启动第二个 EmojiJournalServer 使用现有数据库。

CouchDB容器将其数据库存储在 / opt / couchdb / data 中。 CouchDB容器在后台运行,但是 docker exec 允许您打开交互式终端会话,因此您可以查看。 在 Docker run 终端窗口中运行此命令:

docker exec -it couchdb bash

此命令允许您查看容器的文件系统: docker exec 在您使用 --detach 选项在后台启动的 couchdb 容器上运行其选项。 这里, docker exec 选项是 --interactive--tty ,缩写为 -it - 这些在CouchDB容器中创建了一个交互式终端会话。 您将 bash 指定为要运行的命令 - bash 是一个特定的 Unix shell ,允许您在容器中运行 Unix 命令。 你得到一个以 / opt / couchdb# 结尾的 shell 提示符 - 你已经在 / opt / couchdb 目录中了。 在此提示符下,输入以下命令:

ls -l data

如果您运行另一个 CouchDB 容器,它将无法访问此CouchDB容器的数据库。 删除CouchDB容器也会删除其数据库。 但是,您通常希望在停止和启动CouchDB容器之间保留数据库中的数据。 您可能希望与另一个容器共享一个容器的数据库。

正如您所期望的那样,Docker有办法让您这样做!

Clean up:在 Docker run 终端窗口中,在 bash 提示符下输入 exit 。 停止并移除所有容器。


以上所述就是小编给大家介绍的《Docker应用详细解析(一) —— 在macOS上使用Docker(一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C#本质论

C#本质论

米凯利斯 / 周靖 / 人民邮电出版社 / 2010-9 / 99.00元

《C#本质论(第3版)》是一部好评如潮的语言参考书,作者用一种非常合理的方式来组织《C#本质论(第3版)》的内容,由浅人深地介绍了C#语言的各个方面。全书共包括21章及6个附录,每章开头的“思维导图”指明了本章要讨论的主题,以及各个主题之间的层次关系。书中所包含的丰富的示例代码和精要的语言比较,都有助于读者理解C#语言。《C#本质论(第3版)》首先介绍了C#语言的基础知识,随后深人讲解了泛型、迭代......一起来看看 《C#本质论》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具