这只是一个简单的演示,让您在逐步工作的同时,对 Docker 的工作原理有一个基本的了解。我就这样学习了docker,并制作了这个repo来解决我在学习过程中遇到的一些问题,以便对其他初学者有所帮助。希望您享受学习的乐趣。如果您喜欢它,请在 GitHub 上点赞并支持我的工作。
重要提示:-通过查看自述文件的大小,您可能会重新考虑,但说实话,如果您从头开始工作,您将不会遇到任何问题并一路学习。
维基百科将 Docker 定义为
是一组平台即服务 (PaaS) 产品,它使用操作系统级虚拟化以称为容器的包形式交付软件。容器彼此隔离,并将其软件、库和配置文件捆绑在一起;他们可以通过明确的渠道相互沟通。所有容器都由单个操作系统内核运行,因此比虚拟机使用更少的资源。
Docker 帮助您在沙箱(称为容器)中更有效地部署应用程序,以便在主机操作系统(即 Mac)上运行。 docker 的主要优点是它允许您将软件及其所有依赖项打包到单个标准化单元中。
容器是一种解决方案,用于解决如何让软件在从一个计算环境转移到另一个计算环境时顺利运行的问题。这可能是从暂存环境到生产环境,也可能是从笔记本电脑到具有另一个操作系统的另一台笔记本电脑。
容器提供了一种逻辑打包机制,您的应用程序可以从它们运行的环境中抽象出来。主要区别在于每个容器不需要其成熟的操作系统。单个主机上的所有容器共享单个操作系统。这有助于释放大量的系统资源,例如 CPU、RAM。
安装完 Docker 后,通过运行以下命令来测试 Docker 安装:
docker run hello-world
Hello from Docker.
This message shows that your installation appears to be working correctly.
...
Dockerfile
是一个文本文档,其中包含可以在命令行上调用来制作映像的所有命令。创建文件hello.js
并将此代码复制到其中。这里我们编写了一个简单的 JS 代码来在localhost:8888
上显示 Hello World。 var http = require( " http " ) ;
http.createServer(function (request, response) {
response.writeHead(200, { ' Content-Type ' : ' text/plain ' }) ;
response.end( ' Hello Worldn ' ) ;
}).listen(8888) ;
// Console will print the message
console.log( ' Server running at http://127.0.0.1:8888/ ' ) ;
Dockerfile
的文件并将此代码复制到其中。 FROM node:8
LABEL maintainer= " [email protected] "
RUN npm install
ADD hello.js /hello.js
EXPOSE 8888
ENTRYPOINT [ " node " , " hello.js " ]
即使这是您见过的第一个 Dockerfile,我想说您也可以很好地猜测这里发生了什么。 Dockerfile 指令有 FROM、ENV、LABEL、RUN、ADD、EXPOSE 和 ENTRYPOINT;他们位于首都,但这是惯例,而不是要求。
在较高级别上,此 Dockerfile 提供了诸如从节点映像开始、添加“[email protected]”
作为维护者、运行npm install
以安装依赖项、在应用程序代码中复制文件、记录应用程序的网络端口等指令,并将 hello.js 设置为要运行的默认应用程序。
现在我们将在本地计算机中创建一个 docker 映像。在当前项目的文件夹中打开终端并运行
docker build -t helloworld .
在这里,您告诉 Docker 根据当前目录的内容构建一个名为helloworld
的映像(请注意构建命令末尾的点 (.) )。 Docker会在目录中查找Dockerfile,并根据文件中的指令构建镜像。
构建 docker 映像后,下一步是运行该映像并查看其是否有效:
docker run -p 8888:8888 helloworld
我们刚刚运行的命令使用容器内服务器的端口 8888,并将其暴露在端口 8888 上。转到端口 8888 的 URL:
恭喜!您已成功创建第一个 docker 镜像。
Docker 镜像就像虚拟机模板一样,用于启动容器。在底层,它们由一个或多个只读层组成,当这些层堆叠在一起时,就构成了整体图像。 Docker 负责堆叠这些层并将它们表示为单个统一对象。注意: Docker 镜像是不可变的,这意味着 Docker 镜像永远无法更改。一旦创建,您可以将其删除,但无法修改。
Docker 映像包含您打包的所有文件,这些文件成为容器的文件系统 - 并且它还包含有关映像本身的大量元数据。其中包括图像构建方式的简要历史。您可以使用它来查看图像的每一层以及构建该层的命令。您可以使用以下命令检查helloworld
图像的历史记录:
docker image history helloworld
IMAGE CREATED CREATED BY COMMENT
cb84eb33ca20 58 seconds ago /bin/sh -c # (nop) ENTRYPOINT ["node" "hello…
7d652a817a9f 58 seconds ago /bin/sh -c # (nop) EXPOSE 8888
334575e947c9 59 seconds ago /bin/sh -c # (nop) ADD file:b9606ef53b832e66e…
CREATED BY
命令是 Dockerfile 指令 - 存在一对一的关系,因此 Dockerfile 中的每一行都会创建一个镜像层。
首先,您需要使用您的 dockerhub 帐户登录
docker login --username $dockerId
现在您已登录,您可以将图像推送到您的帐户或您有权访问的任何组织。如果您不是任何组织的成员,则只能将图像推送到您帐户中的存储库。
我们构建了一个名为helloworld
的 Docker 镜像。该图像引用没有帐户名,因此我们无法将其推送到任何注册表。不过,我们不需要重建图像来为其提供新的参考,图像可以有多个参考。像这样标记你的图像:
docker image tag helloworld $dockerId /helloworld:v1
现在我们有了一个镜像引用,帐户名中包含我们的 Docker ID,并且我们登录了 Docker Hub,准备好共享我们的镜像了! docker image push 命令与 pull 命令相对应,它将我们的本地镜像层上传到注册表:
docker image push championshuttler/helloworld:v1
The push refers to a repository [docker.io/championshuttler/helloworld]
9519a21ac374: Pushed
我们可以将任何字符串放入 Docker 镜像标签中,正如我们已经看到的,同一个镜像可以有多个标签。我们将使用它来对我们的图像中的软件进行版本控制,并让用户对他们不会使用的内容做出明智的选择 - 并在我们使用其他人的图像时做出我们自己的明智的选择。
许多软件项目使用带小数点的数字版本控制方案来指示版本之间的变化有多大,您可以使用图像标签来跟踪它。基本思想类似于[major].[minor].[patch],它有一些隐含的保证。仅增加补丁号的版本可能有错误修复,但应具有与上一个版本相同的功能;增加次要版本的版本可能会添加功能,但不应删除任何功能;主要版本可能具有完全不同的功能。
大多数应用程序并不在单个组件中运行。即使大型旧应用程序通常也构建为前端和后端组件,它们是在物理分布式组件中运行的独立逻辑层。 Docker 非常适合运行分布式应用程序 - 从 n 层整体应用程序到现代微服务。每个组件都在其轻量级容器中运行,Docker 使用标准网络协议将它们插入在一起。您可以使用 Docker Compose 定义和管理这样的多容器应用程序。 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用YAML
文件来配置应用程序的服务。然后,通过一个命令,我们可以根据您的配置创建并启动所有服务。
Docker Compose 文件描述了应用程序的所需状态 - 当一切都在运行时它应该是什么样子。这是一种简单的文件格式,您可以将在 docker 容器运行命令中放入的所有选项捕获到 Compose 文件中。然后,您使用 Docker Compose 工具来运行该应用程序。它计算出所需的 Docker 资源(可能是容器、网络或卷),并向 Docker API 发送请求以创建它们。 Compose YAML 文件的默认名称是docker-compose.yml
。但是,我们可以使用-f标志来指定自定义文件名。
让我们开始吧。
下面的代码显示了一个非常简单的Docker Compose
文件,它定义了一个带有两个服务(Web 前端和 Redis)的小型 Flask 应用程序。该应用程序是一个简单的 Web 服务器,用于计算访问次数并将值存储在 Redis 中。
version: " 3.5 "
services:
web-frontend:
build: .
command: python app.py
ports:
- target: 8888
published: 8888
networks:
- counter-net
volumes:
- type: volume
source: counter-vol
target: /code
redis:
image: " redis:alpine "
networks:
counter-net:
networks:
counter-net:
volumes:
counter-vol:
version
密钥是必要的,并且它应该始终位于文件的第一行。这解释了Compose file
格式的版本(基本上是 API)。
顶层services
关键是我们定义不同的应用程序服务的地方。我们使用的示例定义了两个服务;一个名为web-frontend
Web 前端和一个名为 Redis 的内存数据库。 Compose 会将这些服务中的每一个部署为其容器。
顶级networks
密钥告诉 Docker 创建新网络。默认情况下,Compose 将创建桥接网络。这些是单主机网络,只能连接同一主机上的容器。
在 Web 前端服务的定义中,我们为 Docker 提供了以下指令:
我们将部署上一节中 Compose 文件中定义的应用程序。为此,您需要 https://github.com/championsshuttler/counter-app 中的以下 4 个文件:
将 Git 存储库克隆到本地。
git clone https://github.com/championshuttler/counter-app.git
让我们快速描述一下每个文件:
app.py
是应用程序代码(Python Flask 应用程序)。docker-compose.yml
是 Docker Compose 文件,描述 Docker 应如何部署应用程序。Dockerfile
描述了如何构建 Web 前端服务的镜像。requirements.txt
列出了应用程序所需的Python 包。让我们使用 Compose 来启动该应用程序。您必须从counter-app
目录中运行以下所有命令:
docker-compose up &
应用程序需要几秒钟的时间才能启动,并且输出可能非常冗长。
成功部署应用程序后,您可以将 Web 浏览器指向port 5000
上的 Docker 主机,并查看该应用程序的全部功能。
您是否觉得本教程一团糟,还是您觉得很有趣并学到了一些东西?直接将您的想法发送给我或只是创建一个问题。也可以在 Twitter 上找到我,如果您有任何疑问,请随时询问。
我很想听听您对本教程的体验。希望你喜欢学习。如果您喜欢它,请在 GitHub 上给它一个并支持我的工作。