为前端工程师准备的 Docker 教程
这是Docker的简明指南,适合前端开发者使用
为什么要使用docker?
很久以前业务需要其他应用的时候,DevOps团队会在不知道新应用的性能要求的情况下去购买服务器。这将涉及大量猜测工作和浪费可用于其他应用程序的资本和资源。
进入虚拟机或 VM,它允许我们在同一台服务器上运行多个应用程序。但有一个缺点。每个 VM 都需要整个操作系统才能运行。每个操作系统都需要 CPU、RAM 等才能运行,它需要打补丁和许可,这反过来又会增加成本和弹性。
Google 很早就开始使用容器模型来解决 VM 模型的缺点。基本上什么容器模型意味着同一主机上的多个容器使用同一主机,从而释放在其他地方使用的 CPU、RAM。
但它如何帮助我们开发者?
它确保所有开发人员和所有服务器(即生产、部署和测试)的工作环境都是相同的。
任何人都可以在几秒钟内设置项目,无需弄乱配置、安装库、设置依赖项等。
简单来说,docker是一个平台,使我们能够开发、部署、并使用容器运行应用程序
让我们退后一步,容器系统在物理上是什么样子的,它与虚拟机有什么不同。
1.1 VM和Docker之间的区别。
主机和主机的资源在容器里是共享的,但在虚拟机里不是。
我们知道这个,接下来就可以继续深入了解一下。
如何使用docker?
为此,我们需要熟悉一些术语。
1.2 Docker镜像和Docker容器的可视化
Docker 镜像:它是一个可执行文件,其中包含精简版操作系统以及运行应用程序所需的所有库和配置。它有多层堆叠在一起,并表示为单个对象。一个 docker 镜像是使用docker file创建的,我们稍后会讲到。
** Docker容器:**它是Docker镜像的运行实例。可以有许多容器从同一个 docker 镜像运行。
容器化简单的 Node.js 应用程序
我们会尝试容纳非常简单的node.js应用程序,并创建镜像:
你的Node.js应用程序
我们从创建文件夹开始,
mkdir my-node-app
cd my-node-app
让我们在index.js
中创建一个简单的节点服务器,并在那里添加以下代码:
//使用`require`指令加载express模块
var express = require('express')
var app = express()
//定义根URL中的请求响应(/)
app.get('/', function (req, res) {
res.send('Hello World!')
})
//在端口8081上启动侦听服务器
app.listen(8081, function () {
console.log('app listening on port 8081!')
})
并将此文件保存在my-node-app
文件夹中。
现在我们创建一个package.json
文件并在那里添加以下代码:
{
"name": "helloworld",
"version": "1.0.0",
"description": "Dockerized node.js app",
"main": "index.js",
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.16.4"
}
}
此时您不需要在主机中安装 express 或 npm,因为 dockerfile 处理设置所有依赖项、lib 和配置。
DockerFile
让我们创建DockerFile并将其保存在my-node-app folder
中。此文件没有扩展名,名为Dockerfile
。让我们继续向dockerfile添加以下代码。
# Dockerfile
FROM node:8
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
EXPOSE 8081
CMD node index.js
现在我们在这里做的是:
FROM node:8
— 从 docker hub 拉取 node.js docker 镜像,可以在下方链接找到https://hub.docker.com/_/node/
WORKDIR /app
-这是我们代码设置镜像中的工作目录,它被所有后续命令使用, 例如 COPY
, RUN
和 CMD
COPY package.json /app
-这将我们的package.json
从主机 my-node-app
文件夹中复制到我们文件夹中的/app
镜像 。
RUN npm install
— 在我们的镜像中运行这个命令来为我们的应用程序安装依赖项(node_modules)。
COPY . /app
— 我们告诉 docker 从 my-node-app 文件夹复制文件并将其粘贴到 /app
docker 镜像中。
EXPOSE 8081
— 我们使用此命令在容器上公开一个端口。为什么是这个端口?因为在我们的服务器中 index.js 正在侦听 8081。默认情况下,从该镜像创建的容器将忽略对其发出的所有请求。
构建Docker镜像
打开终端,进入您的my-node-app
文件夹,输入以下命令:
# 构建docker映像 docker build -t 镜像名 dockerfile的相对路径
docker build -t hello-world .
此命令在主机上创建一个hello world
映像-t
用于向我们的镜像提供名称,这是** Hello-World **。
.
是docker文件的相对路径,因为我们处于my-node-app
文件夹,我们使用dot表示Docker文件的路径。
您将在命令行上看到一个输出,如下所示:
Sending build context to Docker daemon 4.096kB
Step 1/7 : FROM node:8
---> 4f01e5319662
Step 2/7 : WORKDIR /app
---> Using cache
---> 5c173b2c7b76
Step 3/7 : COPY package.json /app
---> Using cache
---> ceb27a57f18e
Step 4/7 : RUN npm install
---> Using cache
---> c1baaf16812a
Step 5/7 : COPY . /app
---> 4a770927e8e8
Step 6/7 : EXPOSE 8081
---> Running in 2b3f11daff5e
Removing intermediate container 2b3f11daff5e
---> 81a7ce14340a
Step 7/7 : CMD node index.js
---> Running in 3791dd7f5149
Removing intermediate container 3791dd7f5149
---> c80301fa07b2
Successfully built c80301fa07b2
Successfully tagged hello-world:latest
如您所见,它运行了docker文件中的步骤并输出了docker镜像。当您第一次尝试时,将需要几分钟时间,但从下次开始,它将开始使用缓存,构建速度会更快,输出将如上图所示。现在,在您的终端中尝试执行以下命令来查看您的镜像是否存在:
# 获取主机上的镜像列表
docker images
主机中应该有一个镜像列表。类似这样的内容
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest c80301fa07b2 22 minutes ago 896MB
运行Docker容器
创建镜像后,我们可以从该镜像启动容器
# 这是Docker容器运行的默认命令
docker container run -p 4000:8081 hello-world
此命令用于创建和运行Docker容器。
-p 4000:8081
— 这是发布标志,它将主机端口 4000 映射到我们通过 dockerfile 中的公开命令打开的容器端口 8081。现在所有对主机端口 4000 的请求都将被容器端口 8081 监听。
hello-world
— 这是我们之前运行 docker-build 命令时给我们的镜像取的名字。
你会收到一些这样的输出:
app listening on port 8081!
如果你想进入你的容器并安装一个 bash 终端,你可以运行
# 输入容器
docker exec -ti <container id> /bin/bash
为了检查容器是否正在运行,打开另一个终端并输入
docker ps
你应该像这样看到你正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED
`<container id>` hello-world "/bin/sh -c 'node in…" 11 seconds ago
STATUS PORTS NAMES
Up 11 seconds 0.0.0.0:4000->8081/tcp some-random-name
这意味着我们从hello-world镜像创建的id为<container id>
的容器已经启动并运行,并且正在侦听端口8081。
现在我们的Node.js应用程序已经完全容器化了。您可以在浏览器上运行localhost:4000/,您应该会看到如下所示:
1.3 Node.js容器应用
到此您已经将第一个应用程序容器化了。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: