如何使用 Docker 构建 Node.js 应用程序 [快速入门]

介绍

本教程将引导您通过创建一个应用程序图像的静态网站,它使用的 Express框架和 Bootstrap. 然后你将使用该图像构建一个容器,将其推到 Docker Hub,并使用它来构建另一个容器,展示如何重建和扩展你的应用程序。

有关本教程的更详细版本,以及每个步骤的更详细的解释,请参阅 如何使用 Docker 构建 Node.js 应用程序

前提条件

要遵循本教程,您将需要:

  • 在您的服务器上或本地环境中的sudo用户。 * Docker. * Node.js 和npm * Docker Hub 帐户。

步骤 1 — 安装您的应用程序依赖

首先,在您的非根用户主目录中创建您的项目目录:

1mkdir node_project

导航到此目录:

1cd node_project

这将是该项目的根目录。

接下来,创建一个 package.json与您的项目依赖:

1nano package.json

将以下有关项目的信息添加到文件中;请确保用自己的名字和联系信息替换作者信息:

 1[label ~/node_project/package.json]
 2{
 3  "name": "nodejs-image-demo",
 4  "version": "1.0.0",
 5  "description": "nodejs image demo",
 6  "author": "Sammy the Shark <[email protected]>",
 7  "license": "MIT",
 8  "main": "app.js",
 9  "scripts": {
10    "start": "node app.js",
11    "test": "echo \"Error: no test specified\" && exit 1"
12  },
13  "keywords": [
14    "nodejs",
15    "bootstrap",
16    "express"
17  ],
18  "dependencies": {
19    "express": "^4.16.4"
20  }
21}

安装您的项目的依赖性:

1npm install

步骤2 - 创建应用文件

我们将创建一个网站,为用户提供关于鲨鱼的信息。

在主项目目录中打开app.js,定义项目路线:

1nano app.js

将以下内容添加到文件中,以创建 Express 应用程序和 Router 对象,将基础目录、端口和主机定义为变量,设置路径,并与应用程序的静态资产一起安装路由器中间件:

 1[label ~/node_project/app.js]
 2var express = require("express");
 3var app = express();
 4var router = express.Router();
 5
 6var path = __dirname + '/views/';
 7
 8// Constants
 9const PORT = 8080;
10const HOST = '0.0.0.0';
11
12router.use(function (req,res,next) {
13  console.log("/" + req.method);
14  next();
15});
16
17router.get("/",function(req,res){
18  res.sendFile(path + "index.html");
19});
20
21router.get("/sharks",function(req,res){
22  res.sendFile(path + "sharks.html");
23});
24
25app.use(express.static(path));
26app.use("/", router);
27
28app.listen(8080, function () {
29  console.log('Example app listening on port 8080!')
30})

接下来,让我们在应用程序中添加一些静态内容,创建视图目录:

1mkdir views

打开index.html:

1nano views/index.html

将下列代码添加到文件中,将导入 Boostrap 并创建一个 jumbotron 组件,链接到更详细的 sharks.html 信息页面:

 1[label ~/node_project/views/index.html]
 2<!DOCTYPE html>
 3<html lang="en">
 4   <head>
 5      <title>About Sharks</title>
 6      <meta charset="utf-8">
 7      <meta name="viewport" content="width=device-width, initial-scale=1">
 8      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
 9      <link href="css/styles.css" rel="stylesheet">
10      <link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'>
11      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
12      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
13   </head>
14   <body>
15      <nav class="navbar navbar-inverse navbar-static-top">
16         <div class="container">
17            <div class="navbar-header">
18               <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
19               <span class="sr-only">Toggle navigation</span>
20               <span class="icon-bar"></span>
21               <span class="icon-bar"></span>
22               <span class="icon-bar"></span>
23               </button>
24               <a class="navbar-brand" href="#">Everything Sharks</a>
25            </div>
26            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
27               <ul class="nav navbar-nav mr-auto">
28                  <li class="active"><a href="/">Home</a></li>
29                  <li><a href="/sharks">Sharks</a></li>
30               </ul>
31            </div>
32         </div>
33      </nav>
34      <div class="jumbotron">
35         <div class="container">
36            <h1>Want to Learn About Sharks?</h1>
37            <p>Are you ready to learn about sharks?</p>
38            <br>
39            <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a></p>
40         </div>
41      </div>
42      <div class="container">
43         <div class="row">
44            <div class="col-md-6">
45               <h3>Not all sharks are alike</h3>
46               <p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans.</p>
47            </div>
48            <div class="col-md-6">
49               <h3>Sharks are ancient</h3>
50               <p>There is evidence to suggest that sharks lived up to 400 million years ago.</p>
51            </div>
52         </div>
53      </div>
54   </body>
55</html>

接下来,打开名为sharks.html的文件:

1nano views/sharks.html

添加以下代码,导入 Bootstrap 和自定义风格表,并为用户提供有关某些鲨鱼的详细信息:

 1[label ~/node_project/views/sharks.html]
 2<!DOCTYPE html>
 3<html lang="en">
 4   <head>
 5      <title>About Sharks</title>
 6      <meta charset="utf-8">
 7      <meta name="viewport" content="width=device-width, initial-scale=1">
 8      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
 9      <link href="css/styles.css" rel="stylesheet">
10      <link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'>
11      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
12      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
13   </head>
14   <nav class="navbar navbar-inverse navbar-static-top">
15      <div class="container">
16         <div class="navbar-header">
17            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
18            <span class="sr-only">Toggle navigation</span>
19            <span class="icon-bar"></span>
20            <span class="icon-bar"></span>
21            <span class="icon-bar"></span>
22            </button>
23            <a class="navbar-brand" href="#">Everything Sharks</a>
24         </div>
25         <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
26            <ul class="nav navbar-nav mr-auto">
27               <li><a href="/">Home</a></li>
28               <li class="active"><a href="/sharks">Sharks</a></li>
29            </ul>
30         </div>
31      </div>
32   </nav>
33   <div class="jumbotron text-center">
34      <h1>Shark Info</h1>
35   </div>
36   <div class="container">
37      <div class="row">
38         <div class="col-md-6">
39            <p>
40            <div class="caption">Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.</div>
41            <img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
42            </p>
43         </div>
44         <div class="col-md-6">
45            <p>
46            <div class="caption">Other sharks are known to be friendly and welcoming!</div>
47            <img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
48            </p>
49         </div>
50      </div>
51    </div>
52   </body>
53</html>

最后,创建您在index.htmlsharks.html中链接的自定义 CSS 风格表,首先在视图目录中创建一个css文件夹:

1mkdir views/css

打开风格表并添加以下代码,将为我们的页面设置所需的颜色和字体:

 1[label ~/node_project/views/css/styles.css]
 2.navbar {
 3        margin-bottom: 0;
 4}
 5
 6body {
 7        background: #020A1B;
 8        color: #ffffff;
 9        font-family: 'Merriweather', sans-serif;
10}
11h1,
12h2 {
13        font-weight: bold;
14}
15p {
16        font-size: 16px;
17        color: #ffffff;
18}
19
20.jumbotron {
21        background: #0048CD;
22        color: white;
23        text-align: center;
24}
25.jumbotron p {
26        color: white;
27        font-size: 26px;
28}
29
30.btn-primary {
31        color: #fff;
32        text-color: #000000;
33        border-color: white;
34        margin-bottom: 5px;
35}
36
37img, video, audio {
38        margin-top: 20px;
39        max-width: 80%;
40}
41
42div.caption: {
43        float: left;
44        clear: both;
45}

启动应用:

1npm start

如果您在本地工作,请导航到http://your_server_ip:8080localhost:8080

Application Landing Page

点击获取鲨鱼信息按钮,您将看到以下信息页面:

Shark Info Page

您现在有一个应用程序正在运行. 当您准备好时,请通过键入CTRL+C来离开服务器。

步骤 3 – 编写 Dockerfile

在项目的根目录中,创建 Dockerfile:

1nano Dockerfile

将以下代码添加到文件中:

 1[label ~/node_project/Dockerfile]
 2
 3FROM node:10-alpine
 4
 5RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
 6
 7WORKDIR /home/node/app
 8
 9COPY package*.json ./
10
11USER node
12
13RUN npm install
14
15COPY --chown=node:node . .
16
17EXPOSE 8080
18
19CMD [ "node", "app.js" ]

此 Dockerfile 使用 alpine base image并确保应用程序文件由非根 node 用户拥有,由 Docker Node image默认提供。

接下来,将本地节点模块、npm 日志、Dockerfile 和.dockerignore 添加到您的.dockerignore 文件中:

1[label ~/node_project/.dockerignore]
2node_modules
3npm-debug.log
4Dockerfile
5.dockerignore

使用 docker build 命令来构建应用程序图像:

1docker build -t your_dockerhub_username/nodejs-image-demo .

. 指明构建背景是当前目录。

查看您的图片:

1docker images

您将看到以下结果:

1[secondary_label Output]
2REPOSITORY TAG IMAGE ID CREATED SIZE
3your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds ago 895MB
4node 10 f09e7c96b6de 17 hours ago 893MB

运行以下命令以使用此图像构建一个容器:

1docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

检查你的运行容器的列表与 docker ps:

1docker ps

您将看到以下结果:

1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e50ad27074a7 your_dockerhub_username/nodejs-image-demo               "npm start"         8 seconds ago Up 7 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

随着容器运行,您现在可以通过导航您的浏览器到http://your_server_iplocalhost来访问您的应用程序,您将再次看到您的应用程序定位页面:

Application Landing Page

现在你已经为你的应用程序创建了一个图像,你可以将其推到Docker Hub,以便在未来使用。

步骤4 — 使用存储库与图像工作

推动图像的第一步是登录到您的 Docker Hub 帐户:

1docker login -u your_dockerhub_username -p your_dockerhub_password

以此方式登录将创建一个 ~/.docker/config.json 文件,在您的用户的主目录中与您的 Docker Hub 凭证。

使用自己的用户名而不是your_dockerhub_username:

1docker push your_dockerhub_username/nodejs-image-demo

如果您愿意,您可以通过摧毁当前的应用程序容器和图像来测试图像注册表的实用性,并重建它们。

首先,列出您的运行容器:

1docker ps

您将看到以下结果:

1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e50ad27074a7 your_dockerhub_username/nodejs-image-demo   "npm start"         3 minutes ago Up 3 minutes 0.0.0.0:80->8080/tcp nodejs-image-demo

使用输出中列出的CONTAINER ID,停止运行应用程序容器. 请确保以自己的CONTAINER ID替换下面的突出ID:

1docker stop e50ad27074a7

列出你的所有图像与-a旗帜:

1docker images -a

您将看到以下输出与您的图像的名称, your_dockerhub_username/nodejs-image-demo,以及您的构建中的节点图像和其他图像:

 1[secondary_label Output]
 2REPOSITORY TAG IMAGE ID CREATED SIZE
 3your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 7 minutes ago 895MB
 4<none>                                               <none>              e039d1b9a6a0 7 minutes ago 895MB
 5<none>                                               <none>              dfa98908c5d1 7 minutes ago 895MB
 6<none>                                               <none>              b9a714435a86 7 minutes ago 895MB
 7<none>                                               <none>              51de3ed7e944 7 minutes ago 895MB
 8<none>                                               <none>              5228d6c3b480 7 minutes ago 895MB
 9<none>                                               <none>              833b622e5492 8 minutes ago 893MB
10<none>                                               <none>              5c47cc4725f1 8 minutes ago 893MB
11<none>                                               <none>              5386324d89fb 8 minutes ago 893MB
12<none>                                               <none>              631661025e2d 8 minutes ago 893MB
13node 10 f09e7c96b6de 17 hours ago 893MB

使用以下命令删除已停止的容器和所有图像,包括未使用或悬浮的图像:

1docker system prune -a

删除所有图像和容器后,您现在可以从 Docker Hub 提取应用程序图像:

1docker pull your_dockerhub_username/nodejs-image-demo

再次列出你的图片:

1docker images

您将看到您的应用程序图像:

1[secondary_label Output]
2REPOSITORY TAG IMAGE ID CREATED SIZE
3your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 895MB

您现在可以使用步骤 3 的命令重建您的容器:

1docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

列出您的运行容器:

1docker ps
1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo               "npm start"         4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

再次访问http://your_server_iplocalhost,查看正在运行的应用程序。

相关教程

以下是有关本教程的更多详细指南的链接:

您还可以在 从容器到Kubernetes with Node.js上查看更长的系列,该教程是由此改编的。

此外,请参阅我们的完整库 Docker 资源 有关 Docker 的更多信息。

Published At
Categories with 技术
comments powered by Disqus