docker化一个Node.js web应用程序

・7 分钟阅读

创建Node.js应用程序

首先,创建一个包含所有文件的新目录,在此目录中创建一个描述应用程序及依赖项的package.json文件:


{
 "name": "docker_web_app",
 "version": "1.0.0",
 "description": "Node.js on Docker",
 "author": "First Last <first.last@example.com>",
 "main": "server.js",
 "scripts": {
 "start": "node server.js"
 },
 "dependencies": {
 "express": "^4.16.1"
 }
}

使用新的package.json文件,运行npm install,如果你使用的是npm 版本5或更高版本,这将生成一个package-lock.json文件,该文件被复制到Docker镜像。

然后,使用Express.js框架创建一个定义web应用程序的server.js文件:


'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
 res.send('Hello World');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

在接下来的步骤中,了解如何使用Docker官方镜像在Docker容器内运行这个应用程序,首先,你需要建立你的应用程序的Docker镜像。

创建Dockerfile

创建一个Dockerfile的空文件:

touch Dockerfile

在你喜欢的文本编辑器中打开Dockerfile

首先,我们需要从构建的镜像中定义,这里使用最新的LTS (长期支持)版本12node,可以从Docker-Hub


FROM node:12

接下来,创建一个目录来保存镜像内部的应用程序代码,这是应用程序的工作目录:


# Create app directory
WORKDIR /usr/src/app

这个镜像附带了Node.js和NPM,所以我们接下来要做的就是使用npm二进制文件安装你的应用程序依赖项,请注意,如果你使用的是npm version 4或更早版本,将不会生成package-lock.json文件。


# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

注意,我们只复制package.json文件,而不是复制整个工作目录,这允许利用缓存的Docker层,

若要将应用程序的源代码捆绑到Docker镜像内部,请使用COPY指令:


# Bundle app source
COPY . .

你的应用程序绑定到端口8080,因此你将使用EXPOSE指令让docker守护进程映射它:


EXPOSE 8080

这里使用node server.js启动你的服务器:


CMD [ "node", "server.js" ]

你的Dockerfile现在应该如下所示:


FROM node:12

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]

dockerignore文件

使用以下内容在与Dockerfile相同的目录中创建.dockerignore文件:


node_modules
npm-debug.log

这将阻止将本地模块和调试日志复制到Docker镜像,并可能覆盖镜像中安装的模块。

构建镜像

转到有Dockerfile的目录,并运行以下命令来生成Docker镜像,-t标志允许你标记镜像,以便以后使用docker images命令更容易找到镜像:


docker build -t <your username>/node-web-app .

你的镜像现在将由Docker列出:


$ docker images

# Example
REPOSITORY TAG ID CREATED
node 12 1934b0b038d1 5 days ago
<your username>/node-web-app latest d64d3505b0d2 1 minute ago

运行镜像

使用-d的镜像以分离模式运行容器,将容器留在后台,-p标志将公共端口重定向到容器内部的私有端口,运行以前构建的镜像:


docker run -p 49160:8080 -d <your username>/node-web-app

打印应用程序的输出:


# Get container ID
$ docker ps

# Print app output
$ docker logs <container id>

# Example
Running on http://localhost:8080

如果需要进入容器内部,可以使用exec命令:


# Enter the container
$ docker exec -it <container id> /bin/bash

试验

要测试你的应用程序,获取Docker映射的应用程序的端口:


$ docker ps

# Example
ID IMAGE COMMAND ... PORTS
ecce33b30ebf <your username>/node-web-app:latest npm start ... 49160->8080

在上面的示例中,Docker将容器内部的8080端口映射到机器上的49160端口。

现在你可以使用curl (如果需要,通过: sudo apt-get install curl ) :


$ curl -i localhost:49160

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0"
Date: Mon, 13 Nov 2017 20:53:59 GMT
Connection: keep-alive

Hello world

我们希望本教程可以帮助你运行一个简单的Docker Node.js的应用程序。

Yanyan profile image