在Docker中建立Node.js应用的经验与技巧

  这篇教程中展示在Docker中开发和部署node.js的web应用的经验和教训,以在docker中设置 socket.io chat example应用为案例,说明如何实现产品准备阶段的工作,具体有:

  • 真正从node在docker起步开始
  • 不要以root运行任何事情
  • 在开发阶段使用bind保持你的test-edit-reload短循环.
  • 在容器中管理node_modules以便更加rebuild
  • 使用 npm shrinkwrap确保可重复的构建.
  • 在开发阶段和产品阶段共享一个Dockerfile 文件

本教程假设你有一些Docker和Node.js基础。

起步

  我们将开始设置  github 这个项目,这里是起步设置文件Dockerfiledocker-compose.ym

如果没有使用Docker,我们会首先安装Node和其他依赖,然后运行npm init创建新的包,但是如果从docker开始,我们将从创建一个启动容器开始,在这个启动容器中已经安装了node,我们将使用它来设置npm包。

我们需要编写两个文件Dockerfile 和 docker-compose.yml,首先加入下面配置:

FROM node:4.3.2

RUN useradd --user-group --create-home --shell /bin/false app &&\
npm install --global npm@3.7.5

ENV HOME=/home/app

USER app
WORKDIR $HOME/chat

虽然这些配置比较短,但是包含重要几点:

  • 第一行这里指定一个版本,而不是使用‘floating’标签:node:argon 或 node:latest, 这样,如果你或其他人在不同机器上建立这个image,他们会得到相同版本,而不是突然遭遇立即更新伴随让人抓狂的问题出现

  • 第二行创建了一个普通用户在容器中来调用应用,如果你不这么做,容器中过程将作为root运行,有违背安全规则,许多docker教程为了简单都忽视这个设置,这非常重要。

  • 安装最新NPM最新版本. 这是严格必须的,最好在在配置中指定一个准确的版本。.

  • 注意到我们用一行RUN命令执行了useradd和npm install两个本应单行命令,这会降低结果image中层次数量,节省磁盘空间和下载时间,节省中间过程导致的空间浪费。

再看看启动文件docker-compose.yml:

chat:
  build: .
  command: echo 'ready'
  volumes:
    - .:/home/app/chat

这是定义了是从Dockerfile中构建的一个服务,所做的是echo ready并退出,.:/home/app/chat是告诉docker安装当前主机应用目录"."到/home/app/chat目录下,这样能够使得当前主机上源文件自动映射到容器中,对于尽可能在开发阶段保持 test-edit-reload是很重要的。

现在当我们运行docker-compose up时,Docker将按照Dockerfile文件创建带有nodee的image,。它会启动一个容器,然后运行echo命令,显示一切设置OK:

$ docker-compose up
Building chat
Step 1 : FROM node:4.3.2
---> 3538b8c69182
...
lots of build output
...
Successfully built 1aaca0ac5d19
Creating dockerchatdemo_chat_1
Attaching to dockerchatdemo_chat_1
chat_1 | ready
dockerchatdemo_chat_1 exited with code 0

现在我们在容器中运行一个交互shell,在shell中设置初始包:

$ docker-compose run --rm chat /bin/bash
app@e93024da77fb:~/chat$ npm init --yes
... writes package.json ...
app@e93024da77fb:~/chat$ npm shrinkwrap
... writes npm-shrinkwrap.json ...
app@e93024da77fb:~/chat$ exit

至此完成,下面是我们主机的情况:

$ tree
.
├── Dockerfile
├── docker-compose.yml
├── npm-shrinkwrap.json
└── package.json

结果代码在github.

下一步是安装依赖包

 

Node.js专题