(本文翻译自 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