从入门到深入,Docker新手学习教程

图片

图片

编译整理|TesterHome社区

作者Ishaan Gupta

以下为作者观点:

Docker 彻底改变了我们开发、交付和运行应用程序的方式。它使开发人员能够将应用程序打包到容器中 - 标准化的可执行组件,将应用程序源代码与在任何环境中运行该代码所需的操作系统 (OS) 库和依赖项相结合。本文将介绍 docker 的关键概念、安装、命令、构建映像、管理容器、网络、数据持久性以及其他一些高级主题。

那么,让我们开始吧。但在学习 docker 之前,你需要先了解容器/容器化。(本文内容较长,请耐心阅读!)

容器和容器化

什么是容器?

容器是轻量级、独立且可执行的软件包,其中包含运行软件所需的一切,包括代码、运行时、系统工具、库和设置。容器将软件与其环境隔离开来,并确保其能够统一运行,尽管开发和暂存之间存在差异。这意味着它们允许将应用程序及其所有依赖项和库打包成一个单元,该单元可以在任何具有容器运行时(例如 Docker)的机器上运行。

什么是容器化?

容器化是将软件代码及其依赖项打包的过程,以便它可以在任何基础架构上统一一致地运行。此方法可确保应用程序在从一个计算环境移动到另一个计算环境时可以轻松部署并可靠运行。

容器化的好处

  • 一致性:无论应用程序在何处运行,其行为都相同。

  • 效率:容器是轻量级的,共享主机操作系统内核,比虚拟机使用更少的系统资源。

  • 可扩展性:随着应用程序规模逐渐增长,可以轻松地扩大或缩小应用程序的规模。

  • 隔离性:每个容器都在其隔离的环境中运行,提高了安全性和稳定性。

图片

什么是 Docker?

Docker 是一个开源平台,可让开发人员轻松高效地构建、部署、运行、更新和管理容器化应用程序。以下是 Docker 受欢迎的一些主要原因:

Docker 简化了开发工作流程,减少了“它在我的计算机上运行”的问题,并允许高效部署和扩展应用程序。

Docker 的主要优点:

  • 可移植性:无论应用程序部署在何处,其运行方式都相同。

  • 可扩展性:根据需求轻松地扩大或缩小应用程序的规模。

  • 隔离性:容器封装应用程序及其依赖项,确保它们彼此独立运行。

Docker 的历史

Docker于2013 年 3 月由 DotCloud(现为 Docker, Inc.)首次发布。Docker 的理念是创建一种轻量级、可移植且高效的方式,用于在不同环境中一致地打包和运行应用程序。这受到了集装箱运输概念的启发,在集装箱运输概念中,应用程序及其依赖项被打包到可以轻松移动和部署的标准化容器中。

如今,Docker 已在各行各业得到广泛采用,并得到了庞大而活跃的开发者和贡献者社区的支持。它已成为容器化的基础技术,并引发了其他相关技术的发展,例如用于容器编排的 Kubernetes。

Docker入门

在深入了解 Docker 之前,需要在系统上安装它。Docker 适用于多个平台,包括 Windows、macOS 和 Linux。

安装 Docker

按照官方网站上适合的操作系统的说明进行操作。https://docs.docker.com/get-docker/

安装后,验证 Docker 是否正在运行:

docker — version

Docker 架构

了解Docker的架构:

Docker 组件

Docker 使用客户端-服务器架构,包含几个关键组件:

1.Docker 客户端:允许用户与 Docker 交互的命令行界面 (CLI) 工具。它与 Docker 守护程序通信以执行命令。

2.Docker Daemon(或 Docker Engine):Docker Engine 是一种开源容器化技术,允许开发人员将应用程序打包到容器中。容器是标准化的可执行组件,结合了应用程序源代码与在任何环境中运行该代码所需的操作系统 (OS) 库和依赖项。它监听 Docker API 请求并相应地处理它们。

3.containerd:管理容器生命周期的核心组件,包括启动、停止和管理容器进程。

4.runc:一个轻量级的 CLI 工具,用于根据开放容器计划 (OCI) 规范创建和运行容器。

5.Docker Registry:存储和分发 Docker 镜像的服务。Docker Hub 是默认的公共注册表,但也可以使用私有注册表。它类似于 GitHub,但它允许您推送镜像而不是源代码。

6.Docker 网络:为容器提供网络功能,使它们能够相互通信并与外界通信。

7.Docker Volumes 和 Bind Mounts:实现容器和主机系统之间的数据持久性和共享。

8.Docker Compose一种使用 YAML 文件定义和运行多容器应用程序的工具。

图片

Docker 如何运行应用程序

1.构建:Docker 客户端向 Docker 守护进程发送构建请求,Docker 守护进程根据 中的指令创建镜像Dockerfile。

2.运送:图像存储在 Docker 注册表(公共或私有)中,可以从那里下载和共享。

3.运行:Docker 客户端请求 Docker 守护进程根据镜像创建并运行容器。

Docker 镜像

Docker 镜像是一个轻量级、独立的可执行包,其中包含运行软件所需的一切,包括代码、运行时、库、环境变量和配置文件。

拉取 Docker 镜像

你可以从 Docker Hub 中提取镜像:

docker pull hello-world

拉取镜像后,可以使用 docker run 命令轻松运行镜像。

docker 镜像和容器之间的区别可以形象地想象,容器就是你从 github 获取的一些源代码在你的机器上运行 node app.js,而镜像是 github 上的代码库。

图片

基本docker命令

1.检查Docker 版本

docker version

2.查看系统范围的 Docker 信息

docker info

3.列出所有 Docker 镜像

docker images

4.列出正在运行的容器

docker psdocker ps -a      // List All Containers (Running and Stopped)

5.从注册表中提取镜像

docker pull node:20      // Here 20 specifies a specific version of the node we want to pull

6.从映像创建并启动新容器

在下面的例子中,我们以分离模式(-d)部署 NGINX 服务器,将主机端口 8080 映射到容器端口 80。

docker run -d -p 8080:80 nginx

7.停止正在运行的容器并将其删除

docker stop <container_id>docker rm <container_id>                // Remove a Stopped Container

8.删除图像

docker rmi <image_id>

9.构建Docker 映像

docker build -t <your-image-name> .

10.)将镜像推送至注册表

docker push <Name of the image> <Name of the repo>

Docker 端口映射说明

Docker 中的端口映射是将主机上的端口映射到容器中的端口的过程。这对于从 Docker 主机外部访问容器内运行的应用程序至关重要。

端口映射的工作原理

假设有一个在端口 3000 上的 Docker 容器内运行的 Web 服务器。默认情况下,此端口只能在 Docker 网络内访问,而不能从主机或外部网络访问。

为了使该服务器在容器外部可访问,需要将端口从主机转发到容器。

例子:

图片

docker run -p [HOST_PORT]:[CONTAINER_PORT] [IMAGE-NAME]

-p是用于指定端口映射的标志。

Dockerfile

Dockerfile 是一个文本文件,其中包含一系列关于如何构建 Docker 镜像的指令。每条指令都会在镜像中创建一个层,并且这些层会被缓存以加快未来的构建速度。

Dockerfile 中的关键指令:

  • FROM:设置后续指令的基础映像。

  • WORKDIR:设置容器内的工作目录。

  • COPY:将文件从主机系统复制到容器。

  • RUN:在容器中执行命令。

  • CMD:指定容器启动时运行的命令。

  • EXPOSE:记录容器监听的端口。

.dockerignore

.dockerignore 文件的工作方式类似于.gitignore 文件。它指定在构建 Docker 镜像时应忽略哪些文件和目录。这有助于保持镜像的轻量级,避免不必要的文件。这会减少构建上下文的大小,并提高构建时间。添加 node_modules、dist 文件夹等等。

如何构建 docker 镜像?

我们将以将基本的 mongo-express typescript 应用程序 docker 化为例。

1.初始化项目

mkdir ts-express-appcd ts-express-appnpm init -y
npm install express mongoose dotenvnpm install --save-dev typescript @types/node @types/express @types/mongoose ts-nodetsc --init

2.创建 tsconfig.json

{     “compilerOptions” :{         “target” :“ES6” ,        “module” :“commonjs” ,        “outDir” :“。/dist” ,        “rootDir” :“。/src” ,        “strict” :true     } }

3.创建 src/index.ts

import express from 'express';import mongoose from 'mongoose';import dotenv from 'dotenv';
dotenv.config();
const app = express();const PORT = 3000;const DB_URL = process.env.DATABASE_URL || '';
mongoose.connect(DB_URL, { useNewUrlParser: true, useUnifiedTopology: true })    .then(() => console.log('Connected to MongoDB'))    .catch(err => console.error('Could not connect to MongoDB', err));
app.get('/', (req, res) => {    res.send('Ram Ram bhai Sareya Ne');});
app.listen(PORT, () => {    console.log(`Server is running on port ${PORT}`);});

   

4.创建 package.json 文件和 .env 文件

"scripts": {    "start": "node dist/index.js",    "build": "tsc"}    
DATABASE_URL=mongodb://localhost:27017/ts-express-app

5.在项目根目录中创建Dockerfile

# Use the Node.js 20 image as the base imageFROM node:20
# Set the working directory inside the containerWORKDIR /usr/src/app
# Copy package.json and package-lock.jsonCOPY package*.json ./
# Install dependenciesRUN npm install
# Copy the rest of the application codeCOPY . .
# Build the TypeScript codeRUN npm run build
# Expose the port the app runs onEXPOSE 3000
# Command to run the appCMD ["npm", "start"]

6.在项目根目录中创建一个文件:.dockerignore

node_modulesdistnpm-debug.log

7.)构建Docker 映像

docker build -t ts-express-app .

上述命令应该可以成功运行并给出类似如下的输出:

图片

8.)运行Docker容器

构建映像后,可以使用以下命令从中运行容器:

docker run -p 3000:3000 ts-express-app

就像我之前说的,上面的代码运行了你的容器,并将主机上的端口 3000 映射到容器的端口 3000。你可以访问 localhost:3000 并看到容器成功运行。

图片

在上图中,可以看到我的图像列在 docker images 中,我可以看到容器在端口 3000 上运行,该端口与机器端口 3000 映射。花点时间在这里玩一玩,分析一下这里发生了什么。此外,在上面的命令中,我使用了一些我之前没有解释过的额外的东西。找出并了解它是你的家庭作业。如果你找到了它,请在评论部分对其进行评论,并对其进行适当的解释 :)

现在,你可以使用 3 个简单命令将镜像推送到 docker hub 注册表 -

9.将镜像推送到Docker Registry

docker logindocker tag ts-express-app your-dockerhub-username/ts-express-app:latestdocker push your-dockerhub-username/ts-express-app:latest

在上方输入您的 dockerhub 用户名,代替“your-dockerhub-username”。我使用了表达式标签,稍后我会解释,现在请耐心等待!

恭喜你将第一个镜像推送到 dockerhub。现在我相信您已经熟悉了构建镜像和运行容器的基础知识,让我们更深入地了解一下。

现在在生产模式下,你可以隐藏 .env 文件以保护您的机密。那么如何在不使用 .env 文件的情况下将这些 .env 中的机密告知 docker 呢?

只需使用“-e”标志即可将环境变量发送到您的应用程序。

docker run -p 3000:3000 -e DATABASE_URL=mongodb://localhost:27017/ts-express-app ts-express-app

Docker Tags(标签)

Docker 标签传达有关特定镜像版本/变体的有用信息。标签允许你从 Docker 注册表中识别和提取镜像的不同版本。它们是镜像 ID 的别名,通常如下所示:f1477ec11d12。这只是一种引用镜像的方式。一个很好的例子是 Git 标签如何引用你历史记录中的特定提交。

标记 Docker 镜像的一般语法是:

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

如果没有指定标签,Dockerlatest默认使用该标签。

标签使用的两种最常见情况是:

1.在构建镜像时,我们使用以下命令:

docker build -t username/image_name:tag_name .

2. 通过命令明确标记图像tag。

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

3.版本管理:标签通常用于指示镜像的不同版本。例如,您可能有1.0、1.1、2.0等标签,表示主要或次要版本更新。

4.环境或阶段标识:标签可以帮助区分开发、暂存和生产环境。例如,您可能有dev、staging和等标签prod。

5.架构或平台识别:标签可以识别为不同架构或平台构建的图像,例如amd64、arm64或windows。

让我们通过在命令中使用标签来进一步理解它-

1.使用标签构建 Docker 映像:

docker build -t express-mongo-app:1.0 .

2.拉取特定标签:

docker pull node:14.18.0

3.使用新标签标记现有图像:

docker tag express-mongo-app:1.0 express-mongo-app:latest

4.使用标签管理版本:

使用语义版本控制(MAJOR.MINOR.PATCH)—

docker build -t express-mongo-app:1.0.0 .docker tag express-mongo-app:1.0.0 express-mongo-app:1.0docker tag express-mongo-app:1.0.0 express-mongo-app:latest


 

Docker exec 命令

该docker exec命令允许你在正在运行的 Docker 容器内运行命令。这对于调试、运行管理任务、创建文件夹/卷或检查容器的状态非常有用。

基本docker exec用法

docker exec [OPTIONS] CONTAINER_ID|CONTAINER_NAME COMMAND [ARG…]

  • 选项:各种选项,如-it交互模式。

  • CONTAINER:容器的名称或 ID。

  • COMMAND:您想要在容器内运行的命令。

  • [ARG…]:命令的参数。

图片

这将在正在运行的容器内打开一个交互式 Bash shell。然后你可以在容器环境中运行命令、检查文件、创建/删除卷或执行脚本。

选项-it代表docker exec“-interactive -tty”,它允许您与容器的shell进行交互。

现在你可能想知道我上面提到的卷是什么。让我们深入探讨一下!

Docker Volumes

Docker Volumes 是挂载在 Docker 容器上的文件系统,用于保存容器生成的数据。

什么是 Docker 文件系统?

Docker 容器执行 Docker 镜像中指定的软件堆栈。镜像由在 Union File System 上运行的只读层组成。当我们启动新容器时,Docker 会在镜像层之上添加一个读写层,使容器能够像传统的 Linux 文件系统一样运行。因此,容器内的每个文件修改都会在读写层中生成一个可运行的副本。但是,当容器停止或删除时,读写层就会消失。

Docker 管理保存在主机文件系统某个部分(Linux 上为 /var/lib/docker/volumes)中的卷。文件系统的这一部分不应由非 Docker 进程更改。在 Docker 中,卷是存储数据的最有效方式。使用 docker volume create 命令,我们可以直接创建卷,或者 Docker 在创建容器或服务时可以为我们创建卷。

主要有三种类型的卷:

  • Named Volumes:由 Docker 管理并存储在主机文件系统上的某个位置。

  • Bind Mounts:将目录或文件从主机挂载到容器中。在主机系统上,绑定挂载可以保存在任何地方。这些可能是关键的系统文件夹或文件。它们始终可由在 Docker 主机或 Docker 容器中运行的非 Docker 进程修改。相比之下,绑定挂载不如卷有用。

  • tmpfs Mounts:将临时文件系统挂载到容器中,存储在主机的内存中。这些挂载永远不会写入主机系统的文件系统;相反,它们仅保存在主机系统的内存中。无论是在 Docker 主机上还是在容器中,它都不会存储在磁盘上。敏感或非持久状态数据可以在容器的持续时间内存储在 tmpfs 挂载上。

命名卷:

使用以下命令创建命名卷:

docker volume create my-ts-app-data

现在,让我们将卷挂载到容器内的目录中。我们正在将卷挂载my-ts-app-data到/app/data容器内的目录中。写入/app/data容器内的任何数据都将存储在主机上的命名卷中。

docker run -d -p 3000:3000 -e DATABASE_URL=mongodb://mongo:27017/ts-express-app -v my-ts-app-data:/data/db ts-express-app

图片

使用docker volume inspect “my-ts-app-data”命令显示有关卷的详细信息,包括其在主机文件系统上的位置。

要删除不再需要的卷,只需使用“rm”命令。

docker volume rm my-ts-app-data

图片

Docker 中卷的工作

现在,让我们尝试一些新东西。假设我想在 mongoDB 指南针应用中可视化我的数据。但是我如何将它连接到容器中的卷?

通过运行以下命令在本地启动 mongo 容器 -

docker run -p 27017:27017 -d mongo

打开你的mongoDB指南针并连接到27017端口。创建一个数据库和集合并在其中插入一些数据并保存。

图片

添加了一个新的数据库和一些随机数据

现在终止容器,然后重新启动它。打开 mongoDB 指南针并检查我们之前创建的数据库和数据。你看到了什么?它不见了,对吧。

图片

那么我们如何保存数据?你猜对了。使用卷!


我们之前已经创建了一个名为“my-ts-app-data”的卷,我们只使用它。将卷挂载到 mongo 容器的/data/db目录中,然后使用以下命令运行它。

docker run -d -v my-ts-app-data:/data/db -p 27017:27017 mongo

现在重复上述步骤,创建一个数据库并在其中添加数据。关闭容器,重新启动它并重新检查您之前输入的数据。您将看到您的数据已持久保存!

现在,既然我们已经了解了命名卷,现在让我们深入研究一些核心 docker 主题。正如您在上面注意到的,我在解释 docker 卷时使用了“层”这个词。但什么是层?让我们看看……

Docker 中的层(Layers In Docker)

到目前为止,我们知道 Docker 构建由一系列有序的构建指令组成。Dockerfile 中的每个指令大致转换为一个层,也称为镜像层。当您从镜像创建新容器时,会在镜像层顶部添加一个新的可写层,从而允许容器进行更改而无需修改底层镜像层。

什么是 Docker 层?

1.基础层:这是 Docker 镜像的起点。它包含操作系统,例如 Ubuntu、Alpine 等等(无论您的 dockerfile 指定什么)。此层是不可变的,并作为后续层的基础。

2.中间层:这些层代表 Dockerfile 中的指令,例如RUN、COPY和ADD。每条指令都会在前一条指令之上创建一个新层。中间层是只读且缓存的。

3.顶部读/写层:当您从镜像运行容器时,Docker 会在只读镜像层之上添加一个可写层。这允许容器进行更改而无需修改底层镜像。

4.可重复使用和可共享:层可缓存并可在不同的镜像之间重复使用,从而提高镜像的构建和共享效率。如果多个镜像是从同一个基础镜像构建的,或者共享通用指令,则它们可以重复使用相同的层,从而减少存储空间并加快镜像下载和构建速度。

如何创建图层

层是根据 Dockerfile 中指定的指令创建的。Dockerfile 中的每个指令都会在先前的层之上生成一个新层。以下是 Dockerfile 示例:

FROM ubuntu: 18.04      // This instruction creates a base layer by pulling the ubuntu: 18.04 image from the Docker registry.
COPY . /app            // This instruction creates a new layer on top of the base layer. It copies the entire contents of the build context (the directory containing the Dockerfile) into the /app directory inside the container.
RUN make /app          // This instruction creates another layer by running the make /app command inside the container. This command builds the application located in the /app directory.
CMD python /app/app.py  // This creates a new layer and specifies the default command to run when the container starts, which is python /app/app.py.                                              


       
在上图中我们可以看到,每条指令都会在之前的指令之上创建一个新层,形成一个层堆栈,构成最终的 Docker 镜像。为了更加直观,您可以参考下图来了解这里到底发生了什么。

图片

图层的图像表示

层缓存(Layer Caching)

当我们使用 Dockerfile 构建 Docker 镜像时,Docker 会按顺序处理每条指令并为每个指令创建一个新层。如果镜像的某个层未更改,则 Docker 构建器会从构建缓存中获取该层。如果某个层自上次构建以来发生了变化,则必须重建该层及其后面的所有层。让我用一个例子来解释一下——

图片

首次构建图像

图片

对 app.js 文件进行微小修改,第二次构建图像

正如你在上面的屏幕截图中看到的,在第一张图片中,我已经将我的 express 应用程序构建为一个图像,我们可以看到每个层都是从头开始构建的。现在我做了一个小改动(只是console.log('hi')在 app.js 文件中添加了一个,现在我正在重建图像。所以现在在第二张图片中你可以看到第 2、3、4 层被缓存,因为它们没有变化,但是由于文件发生了变化,docker 确认了该变化,因此第 5 层没有被缓存并从头开始构建。并且由于第 5 层已更改,因此在其上构建的所有层(在其之后)都将从头开始重建。

注意:尽管截图中仍未显示缓存,但图 2 中的第 1 层仍处于缓存状态。我其实不知道为什么,如果您发现了,请在评论中告诉我。不过不用担心,它确实被缓存了。

现在,你已经对将应用程序 docker 化以及其内部工作原理以及 docker 中的层有了很好的了解。现在,在继续前进之前,请稍事休息,摆弄卷,创建它们并在软件中访问它们。还可以通过构建和重建它们,使用多个基于技术堆栈的应用程序来玩转您的 dockerfile。尝试优化 dockerfile 以减少步骤/层,并最大限度地利用缓存层来提高效率。

Docker 网络

默认情况下,Docker 容器无法相互通信。因此,docker 网络允许容器相互通信并与外界通信。它们支持隔离、安全性以及对 Docker 容器之间通信的控制。

图片

Docker 网络的类型

Docker 提供了几种类型的网络:

1.桥接网络:

独立容器的默认网络类型。桥接网络在主机和容器之间创建基于软件的桥梁。连接到网络的容器可以相互通信,但它们与网络外部的容器隔离。网络中的每个容器都分配有自己的 IP 地址。由于网络桥接到主机,因此容器也能够在 LAN 和互联网上通信。但它们不会作为物理设备出现在 LAN 上。

2.主机网络:

使用主机网络模式的容器共享主机的网络堆栈,没有任何隔离。它们没有分配自己的 IP 地址,端口绑定将直接发布到主机的网络接口。这意味着侦听端口 80 的容器进程将绑定到<your_host_ip>:80

3.覆盖网络:

覆盖网络是跨多个 Docker 主机的分布式网络。该网络允许任何主机上运行的所有容器相互通信,而无需操作系统级路由支持。覆盖网络实现了 Docker Swarm 集群的网络,但当您运行两个单独的 Docker Engine 实例且容器必须直接相互联系时,您也可以使用它们。这允许您构建自己的类似 Swarm 的环境。

4.Macvlan网络:

Macvlan 是另一个高级选项,它允许容器作为物理设备出现在您的网络上。它的工作原理是为网络中的每个容器分配一个唯一的 MAC 地址。此网络类型要求您将主机的一个物理接口专用于虚拟网络。还必须适当配置更广泛的网络,以支持运行许多容器的活动 Docker 主机可能创建的大量 MAC 地址。

5.ipvlan:

IPvLAN 是一种驱动程序,可精确控制分配给容器的 IPv4 和 IPv6 地址,以及第 2 层和第 3 层 VLAN 标记和路由。当您将容器化服务与现有物理网络集成时,此驱动程序非常有用。IPvLAN 网络分配有自己的接口,与基于桥接的网络相比,它具有性能优势。

6. 无网络:

隔离的、没有网络接口的容器。

让我们尝试让容器互相对话。

使用以下命令创建网络(默认情况下它是桥接网络):—

当您运行一个容器而没有指定网络时,它将连接到桥接网络。

docker network create my-first-networkdocker network ls

在 Bridge 网络上运行容器 —

docker run -d --name c1 --network my-first-network nginxdocker run -d --name c2 --network my-first-network nginx

现在让我们将容器 1 连接到容器 2,我们将进入 c1,然后 ping c2

docker exec -it c1 /bin/bash ping c2

你可以看到它正在运行。现在让我们尝试一些新东西。我将在一个容器中运行 mongo,在另一个容器中运行我的 express 应用程序,然后尝试通过我的 express 应用程序访问 mongo 容器。使用我们之前创建的相同的 express 应用程序代码,只需在下面的 .env 文件中即可 ——

DATABASE_URL=[container_name]://mongodb:27017/ts-express-app-dbDATABASE_URL=mongodb://mongodb:27017/ts-express-app-db
docker run -d --name mongodb --network my-first-network -v my-ts-app-data:/data/db -p 27017:27017 mongodocker run -d -p 3000:3000 --network my-first-network -e DATABASE_URL='mongodb://mongodb:27017/ts-express-app-db' ts-express-appYou can see both container up, now try adding some data using postman or curl command in your terminal. You will see a success response, to confirm that the data is in mongodb, you can go inside the container and run below mongo commands.
docker exec -it mongodb mongo
use mydatabase
db.users.find().pretty()

你还可以检查 mongoDB 的容器日志来确认数据是否存储。

删除网络——

docker network rm my-first-network
# remove all unused network (networks that aren't connected to even a single container)docker network prune

断开容器与网络的连接——

docker network disconnect my-first-network mongodb

Docker 组成

Docker Compose 是一款可用于定义和运行多容器 Docker 应用程序的工具。它使用 YAML 文件 ( docker-compose.yml) 来配置和编排组成应用程序的服务,包括它们的依赖项、网络、卷和其他配置设置。

到目前为止,我们一直在使用的 Express 应用程序的docker-compose.yml文件示例:

version: '3.9'
services:  ts-express-app:    build: .    image: "express-mongo-ts-docker"    container_name: ts-express-app    ports:      - "3000:3000"    environment:      - MONGO_URL=mongodb://mongodb:27017/ts-express-app-db    depends_on:      - mongodb
  mongodb:    image: mongo    container_name: mongodb    volumes:      - my-ts-app-data:/data/db    ports:      - "27017:27017"
volumes:  my-ts-app-data:

让我们逐行解释一下上述文件的含义——

1.版本声明:

version: '3.9':指定Docker Compose文件格式的版本。

2.服务:

服务是部署单元,用于定义要使用哪个容器镜像。我在上面的文件中定义了 2 个服务

a.) ts-express-app

这项服务定义了我们的 Express 应用程序。

  • build: 从当前目录中的 Dockerfile 构建 Docker 镜像。

  • image: "express-mongo-ts-docker":将图像命名为express-mongo-ts-docker。(可选添加)

  • container_name: ts-express-app:设置容器名称为ts-express-app。

  • ports: - "3000:3000":端口映射照常,无需解释。

  • environment: - MONGO_URL=mongodb://mongodb:27017/ts-express-app-dbMONGO_URL:设置我们的应用用于连接 MongoDB 的环境变量。此 URL 指向mongodb下面 Compose 文件中定义的服务。

  • depends_on: - mongodb:确保ts-express-app服务在服务后启动mongodb。

B)mongodb:

该服务定义 MongoDB 数据库。

  • image: mongo:使用来自 Docker Hub 的官方 MongoDB 镜像。

  • container_name: mongodb:设置容器名称为mongodb。

  • volumes: - my-ts-app-data:/data/db:将 Docker 卷挂载my-ts-app-data到/data/db容器中,这是 MongoDB 存储数据的地方。(同样,我们之前已经学过这一点,因此需要深入解释)

  • ports: - "27017:27017":端口映射照常(再次无需解释……呼……)

3.卷Volumes

my-ts-app-data:我们在文件末尾定义了我们在这里使用的卷。

好的,既然我们已经学会了编写文件,请复制上述代码并docker-compose.yml在应用程序的根目录中定义一个文件。然后进入终端并运行命令docker-compose up --build,等待它构建您的图像并启动容器。您将看到成功消息,现在您的 mongo 和 express 应用程序容器终于在同一个网络上运行,并正确连接到我们定义的卷,可供使用。

要停止应用程序,请使用命令 -docker-compose down

下面是我们的 docker 仪表板的图片,可以在其中看到一个 docker 容器在我们正在运行的两个容器中运行(我们的 mongo 和 express 应用程序)。在第三张图片中,我使用 POSTMAN 添加了一些数据,然后使用 GET req 从我们的数据库中检索了数据。

图片

图片

图片

很简单,不是吗!:)

此外,我们还可以定义如下所示的自定义网络和一些其他自定义的自解释内容。如果我们没有像上面那样定义网络,docker 将自动为我们的服务创建一个默认网络。此默认网络通常以我们的 docker-compose.yml 文件所在的项目目录命名。

我还在下面附加了我们的 express 应用程序的 github 存储库链接,只需克隆、安装库、按照文件中的定义创建卷docker-compose.yml并运行docker-compose up --build命令即可。

是的,就是这样。这就是你的docker-compose主要目标!剩下的就等你去探索了!

在 docker 中还有很多更高级的东西需要学习,但本文就讲到这里。我很快就会写这篇文章的第二部分,其中一部分是关于 kubernetes 的。到那时,我们就可以练习今天学到的东西了。

最后的想法

在本文中,我通过示例介绍了 docker 的几乎所有基本概念。我尝试解释初学者需要了解的所有内容,我可以自信地说,你已经为 docker 做好准备了!

我希望你理解并能理解其中的大部分内容,我知道这篇文章可能会很长,但请相信我,我试图总结初学者开始使用 docker 所需的一切。像往常一样,遇到麻烦或想自己尝试使用 docker 的新事物时,请务必阅读官方文档(https://docs.docker.com/guides/)的具体内容。(原文链接:https://levelup.gitconnected.com/docker-beginner-to-expert-tutorial-68555aa3e544)


由TesterHome社区主办的MTSC2024第十三届中国互联网测试开发大会,将于2024年7月20日在上海举行。

大会日程:主会场+5个平行专场(LLM测试创新、质量保障、效能提升、游戏、智能终端质效),详情:MTSC2024上海大会主会场、五大专场→议题亮点

8折优惠购票限期发售中!(扫描下方图片二维码了解详情)

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

InspireFace-商用级的跨平台开源人脸分析SDK

InspireFace-商用级的跨平台开源人脸分析SDK InspireFaceSDK是由insightface开发的⼀款⼈脸识别软件开发⼯具包&#xff08;SDK&#xff09;。它提供了⼀系列功能&#xff0c;可以满⾜各种应⽤场景下的⼈脸识别需求&#xff0c;包括但不限于闸机、⼈脸⻔禁、⼈脸验证等。 该S…

ubuntu22 sshd设置

专栏总目录 一、安装sshd服务 sudo apt updatesudo apt install -y openssh-server 二、配置sshd 使用文本编辑器打开/etc/ssh/sshd_config sudo vi /etc/ssh/sshd_config &#xff08;一&#xff09;配置sshd服务的侦听端口 建议将ssh的侦听端口改为7000以上的端口&#…

【bazel】快速下载教程

bazel下载链接&#xff1a; https://github.com/bazelbuild/bazel/releases?page11 直接在github上下载&#xff0c;会因为网络不稳定&#xff0c;而频繁下载错误 这里提供一个超级快速的方法&#xff01;&#xff01;&#xff01; 用迅雷下载&#xff01; 1.从github上复…

【力扣 - 每日一题】3115. 质数的最大距离(一次遍历、头尾遍历、空间换时间、埃式筛、欧拉筛、打表)Golang实现

原题链接 题目描述 给你一个整数数组 nums。 返回两个&#xff08;不一定不同的&#xff09;质数在 nums 中 下标 的 最大距离。 示例 1&#xff1a; 输入&#xff1a; nums [4,2,9,5,3] 输出&#xff1a; 3 解释&#xff1a; nums[1]、nums[3] 和 nums[4] 是质数。因此答…

算法系列--分治排序|再谈快速排序|快速排序的优化|快速选择算法

前言:本文就前期学习快速排序算法的一些疑惑点进行详细解答,并且给出基础快速排序算法的优化版本 一.再谈快速排序 快速排序算法的核心是分治思想,分治策略分为以下三步: 分解:将原问题分解为若干相似,规模较小的子问题解决:如果子问题规模较小,直接解决;否则递归解决子问题合…

策略模式的应用

前言 系统有一个需求就是采购员审批注册供应商的信息时&#xff0c;会生成一个供应商的账号&#xff0c;此时需要发送供应商的账号信息&#xff08;账号、密码&#xff09;到注册填写的邮箱中&#xff0c;通知供应商账号信息&#xff0c;当时很快就写好了一个工具类&#xff0…

Python 学习中什么是字典,如何操作字典?

什么是字典 字典&#xff08;Dictionary&#xff09;是Python中的一种内置数据结构&#xff0c;用于存储键值对&#xff08;key-value pair&#xff09;。字典的特点是通过键来快速查找值&#xff0c;键必须是唯一的&#xff0c;而值可以是任何数据类型。字典在其他编程语言中…

vue实现搜索文章关键字,滑到指定位置并且高亮

1、输入搜索条件&#xff0c;点击搜索按钮 2、滑到定位到指定的搜索条件。 <template><div><div class"search_form"><el-inputv-model"searchVal"placeholder"请输入关键字查询"clearablesize"small"style&quo…

对于老百姓而言VR到底能做什么?

VR技术自诞生以来不断发展&#xff0c;已经广泛应用于教育、医疗、工程、军事、航空、航海、影视、娱乐等方面&#xff0c;譬如&#xff0c;大型工程或军事活动VR预演可以大幅度减少人力物力投入&#xff1b;在航空领域&#xff0c;航天飞行员在训练舱中面对屏幕进行各种驾驶操…

【Linux进阶】文件系统4——文件系统特性

1.磁盘组成与分区的复习 首先说明一下磁盘的物理组成&#xff0c;整块磁盘的组成主要有&#xff1a; 圆形的碟片&#xff08;主要记录数据的部分&#xff09;&#xff1b;机械手臂&#xff0c;与在机械手臂上的磁头&#xff08;可擦写碟片上的数据);主轴马达&#xff0c;可以…

打开浏览器控制台,点击应用,浏览器崩溃

调试的时候&#xff0c;打开控制台&#xff0c;点击 “应用” 立马浏览器奔溃&#xff0c;但是点击别的没问题 调查发现是因为manifest.json这个文件引起的 manifest.json 最主要的原因是因为没有设置这个sizes字段 Google浏览器更新大概到126之后的版本会有问题&#xff0c;之…

AI多模态教程:Qwen-VL多模态大模型实践指南

一、模型介绍 Qwen-VL&#xff0c;由阿里云研发的大规模视觉语言模型&#xff08;Large Vision Language Model, LVLM&#xff09;&#xff0c;代表了人工智能领域的一个重大突破。该模型具有处理和关联图像、文本、检测框等多种类型数据的能力&#xff0c;其输出形式同样多样…

代码随想录Day69(图论Part05)

并查集 // 1.初始化 int fa[MAXN]; void init(int n) {for (int i1;i<n;i)fa[i]i; }// 2.查询 找到的祖先直接返回&#xff0c;未进行路径压缩 int.find(int i){if(fa[i] i)return i;// 递归出口&#xff0c;当到达了祖先位置&#xff0c;就返回祖先elsereturn find(fa[i])…

基于Python爬虫的城市二手房数据分析可视化

基于Python爬虫的城市二手房数据分析可视化 一、前言二、数据采集(爬虫,附完整代码)三、数据可视化(附完整代码)3.1 房源面积-总价散点图3.2 各行政区均价3.3 均价最高的10个小区3.4 均价最高的10个地段3.5 户型分布3.6 词云图四、如何更换城市一、前言 二手房具有价格普…

CSS position属性之relative和absolute

目录 1 参考文章2 五个属性值3 position:static4 position:relative&#xff08;相对&#xff09;5 position:absolute&#xff08;绝对&#xff09; 1 参考文章 https://blog.csdn.net/lalala_dxf/article/details/123566909 https://blog.csdn.net/WangMinGirl/article/deta…

最灵活且易用的C++开源串口通信调试软件

这款C开源串口调试软件&#xff0c;集成了丰富的功能&#xff0c;为用户提供高效、便捷的串口通信调试体验。以下是其核心功能亮点&#xff1a; 基础功能&#xff1a; 数据交互自如&#xff1a;支持串口数据的轻松读取与发送&#xff0c;让数据交换变得简单直接。 灵活配置参…

基于顺序表的通讯录实现

一、前言 基于已经学过的顺序表&#xff0c;可以实现一个简单的通讯录。 二、通讯录相关头文件 //Contact.h #pragma once#define NAME_MAX 20 #define TEL_MAX 20 #define ADDR_MAX 20 #define GENDER_MAX 20typedef struct PersonInfo {char name[NAME_MAX];char gender[G…

Python的招聘数据分析与可视化管理系统-计算机毕业设计源码55218

摘要 随着互联网的迅速发展&#xff0c;招聘数据在规模和复杂性上呈现爆炸式增长&#xff0c;对数据的深入分析和有效可视化成为招聘决策和招聘管理的重要手段。本论文旨在构建一个基于Python的招聘数据分析与可视化管理系统。 该平台以主流招聘平台为数据源&#xff0c;利用Py…

昇思25天学习打卡营第2天|MindSpore快速入门

打卡 目录 打卡 快速入门案例&#xff1a;minist图像数据识别任务 案例任务说明 流程 1 加载并处理数据集 2 模型网络构建与定义 3 模型约束定义 4 模型训练 5 模型保存 6 模型推理 相关参考文档入门理解 MindSpore数据处理引擎 模型网络参数初始化 模型优化器 …

如何选择TikTok菲律宾直播网络?

为了满足用户对于实时互动的需求&#xff0c;TikTok推出了直播功能&#xff0c;让用户能够与粉丝即时交流。本文将探讨如何选择适合的TikTok菲律宾直播网络&#xff0c;并分析OgLive是否是值得信赖的选择。 TikTok菲律宾直播网络面临的挑战 作为全球领先的短视频平台&#xff…