标签 node.js 下的文章

Docker 部署一个 Node.js Web 项目[译]

(本文翻译自 Node.js 官方网站的帮助文档)

这个例子的目的是,向你展示如何将一个 Node.js 项目部署到 Docker 容器。这篇指导只适用于开发环境,不适合生产环境。这篇指导也假定你已经成功安装了 Docker,而且对 Node.js 项目的结构有一个基本的认识。

在这篇指导的第一部分,我们将用 Node.js 创建一个简单的 Web 应用,然后我们为那个应用构建一个 Docker 镜像,最后我们来运行这个镜像,作为一个容器。

在软件开发中,Docker 允许你打包一个应用,包含它的全部依赖程序,产生一个标准化的单元,叫作容器。容器是一个最小化的、基础的 Linux 操作系统。镜像是加载到容器的软件。

创建 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.13.3"
  }
}

然后创建名为 server.js 的文件,它用 Express.js 框架定义了一个 Web 应用:

'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\n');
});

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

在下面的步骤,我们将看到你如何用官方的 Docker 镜像,在容器中运行这个应用。首先,你要用你的应用构建一个 Docker 镜像。

创建 Dockerfile

创建一个空文件叫 Dockerfile

touch Dockerfile

用你喜欢的文本编辑器打开 Dockerfile 这个文件。

第一件事,我们要做的是指定从哪个镜像构建。这里我们使用最新的 LTS(long term support) 版本,在 Docker hub 上可获取的 boron 版本的 node

FROM node:boron

下一步我们在镜像中创建一个目录,存放项目代码,这将是项目的工作目录。

# Create app directory
WORKDIR /usr/src/app

这个镜像中已经安装了 Node.js 和 NPM 软件,所以下一步我们要做的是使用 NPM 安装项目的依赖程序。请注意,如果你使用的是 NPM 5 或者更高版本,你还需要复制 package-lock.json,这个文件是在运行 npm install 时生成的:

# Install app dependencies
COPY package.json .
# For npm@5 or later, copy package-lock.json as well
# COPY package.json package-lock.json ./

RUN npm install

注意,相比复制整个工作目录,我们只是复制了 package.json 文件。这允许我们利用 Docker 缓存层。bitJudo 对此有更好的解释

使用 COPY 指令,将项目源代码打包进 Docker 镜像:

# Bundle app source
COPY . .

你的应用绑定在 8080 端口,因此你要用 EXPOSE 指令将它暴露出来:

EXPOSE 8080

最后,指定运行应用的命令 CMD,它定义了运行时。这里我们使用 npm start 命令,它将运行 node server.js 来启动服务器。

CMD [ "npm", "start" ]

现在你的 Dockerfile 应该是下面这个样子:

FROM node:boron

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json .
# For npm@5 or later, copy package-lock.json as well
# COPY package.json package-lock.json ./

RUN npm install

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "npm", "start" ]

.dockerignore 文件

Dockerfile 文件所在的目录中创建一个 .dockerignore 文件,内容如下:

node_modules
npm-debug.log

这可以避免本地的模块和 debug 日志文件被复制到 Docker 镜像中,也可以避免镜像内部安装的模块。

创建镜像

进入 Dockerfile 所在的目录,执行下面的命令来构建 Docker 镜像。-t 参数给你的镜像打一个标签(相当于镜像名称),这样可以更容易通过 docker images 命令找到它:

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

现在用 Docker 命令列出你的镜像如下:

$ docker images

# Example
REPOSITORY                      TAG        ID              CREATED
node                            boron      539c0211cd76    3 weeks ago
<your username>/node-web-app    latest     d64d3505b0d2    1 minute ago

运行镜像

用 -d 参数使镜像运行在 detach 模式,也就是让容器在后台运行。-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
Date: Sun, 02 Jun 2013 03:53:22 GMT
Connection: keep-alive

Hello world

我们希望这个教程,帮助你在 Docker 中运行一个简单的 Node.js 应用程序。

原文:Dockerizing a Node.js web app