您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
使用Docker开发NodeJs APP
 
作者:Joe.Huang 来源:博客园  发布于 2015-1-26
   次浏览      
 

这是两篇连载文章的第一篇,讲解了如何使用 Docker 替代 Vagrant 开发基于 Express 框架的NodeJs App的部分细节。不过,这次要增加点难度:我们要使用 connect-redis 在 Redis 中实现 session 功能。

The Node App

这个 App 由一个 package.json , server.js 和 .gitignore 文件组成,就这么简简单单:

gitignore :

1  node_modules/*

package.json :

{
     "name": "docker-dev", 
     "version": "0.1.0", 
     "description": "Docker Dev", 
     "dependencies": { 
         "connect-redis": "~1.4.5", 
         "express": "~3.3.3", 
         "hiredis": "~0.1.15", 
         "redis": "~0.8.4" 
     } 
 }

server.js :

var express = require('express'),
    app = express(),
    redis = require('redis'),
    RedisStore = require('connect-redis')(express),
    server = require('http').createServer(app);

app.configure(function() {
  app.use(express.cookieParser('keyboard-cat'));
  app.use(express.session({
        store: new RedisStore({
            host: process.env.REDIS_HOST || 'localhost',
            port: process.env.REDIS_PORT || 6379,
            db: process.env.REDIS_DB || 0
        }),
        cookie: {
            expires: false,
            maxAge: 30 * 24 * 60 * 60 * 1000
        }
    }));
});

app.get('/', function(req, res) {
  res.json({
    status: "ok"
  });
});

var port = process.env.HTTP_PORT || 3000;
server.listen(port);
console.log('Listening on port ' + port);

Server.js 处理了依赖关系并启动了一个Express App,这个Express App 配置了 Redis 里存储的 Session 信息并曝露了一个端点(endpoint)用来返回标准 json 格式的服务器状态信息。

这里需要稍微注意的是,Redis 的连接信息会被使用的环境变量所覆盖--后面发布时会有用到这一信息。

The Dockerfile

为了便于开发,我们会把 redis 和 node 运行在同一个容器里,要实现这点,就必须用 Dockerfile 来配置容器 :

Dockerfile :

FROM dockerfile/ubuntu

MAINTAINER Abhinav Ajgaonkar 

# Install Redis
RUN   \
  apt-get -y -qq install python redis-server

# Install Node
RUN   \
  cd /opt && \
  wget http://nodejs.org/dist/v0.10.28/node-v0.10.28-linux-x64.tar.gz && \
  tar -xzf node-v0.10.28-linux-x64.tar.gz && \
  mv node-v0.10.28-linux-x64 node && \
  cd /usr/local/bin && \
  ln -s /opt/node/bin/* . && \
  rm -f /opt/node-v0.10.28-linux-x64.tar.gz

# Set the working directory
WORKDIR   /src

CMD ["/bin/bash"]

让我们逐行逐行来看看 Docherfile 里的代码:

 FROM dockerfile/ubuntu

告诉 Docker 用 Docker 公司提供的 dockerfile/ubuntu 的镜像文件作为 build 时的基础镜像。

1 RUN  \
2   apt-get -y -qq install python redis-server

基础镜像本身并没有任何东西,所以,我们需要用 apt-get 命令将所需要的组件打包进去。这条表示安装 python和 redis-server,Redis 服务是必需的,因为我们要把 session 信息存储进去。对于 npm 而言,python 可以为 Redis Node 生成 C 扩展。

RUN  \
  cd /opt && \
  wget http://nodejs.org/dist/v0.10.28/node-v0.10.28-linux-x64.tar.gz && \
  tar -xzf node-v0.10.28-linux-x64.tar.gz && \
  mv node-v0.10.28-linux-x64 node && \
  cd /usr/local/bin && \
  ln -s /opt/node/bin/* . && \
  rm -f /opt/node-v0.10.28-linux-x64.tar.gz

下载并解压 64 位二进制版 NodeJs。

1 WORKDIR  /src

这句话是告诉 Docker -- 容器开始运行时进入 cd /src 目录。

1 CMD ["/bin/bash"]

此为最后一步:启动 /bin/bash.

Build and run the container

Docker file 配置好后,我们来生成一个 Docker 镜像:

1 docker build -t sqldump/docker-dev:0.1 .

生成成功后,就可以用下面的命令启动容器了:

1 docker run -i -t --rm \
2            -p 3000:3000 \
3            -v `pwd`:/src \
4            sqldump/docker-dev:0.1

我们来分析一下这个命令。

-i: 以交互模式运行容器 (不同于 -d : 以分离模式运行容器),这意味着交互回话 session 结束时,容器就会停止运行。

-t : 分配了一个虚拟终端(pseudo-tty)。

--rm : 停止运行时移除容器和文件系统。

-p 3000:3000 :主机端口 3000 : 容器端口 3000

1 -v `pwd`:/src

这条命令把主机的当前工作目录(如,项目文件)载入容器的/src里面。我们载入文件而不是使用 add 命令增加文件,这使得我们在文本编辑器里更爱文件后能立刻在容器里看到效果。

sqldump/docker-dev:0.1 : 当前运行的 docker 镜像的名字和版本号与我们生成的镜像是一样的。

由于 Dockerfiles 指定了 CMD ["/bin/bash"],容器运行后我们就进入了一个 bash shell。如果 docker 成功运行了命令,情景应该如下图:

Start Developing

容器现在已经运行起来了,不过,在开始编写代码之前,需要将一些标配的,非 docker 文件分别安装。首先,用如下命令在容器里启动 redis 服务:

1 service redis-server start

然后,安装相关依赖和 nodemon 。Nodemon 可以实时监听项目文件的变化并重启服务。

1 npm install
2 npm install -g nodemon

最后,用如下命令启动服务:

1 nodemon server.js

现在,打开你的浏览器并访问:http://localhost:3000,顺利的话会出现下图情景:

给 server.js 增加一个端点以模拟开发工作流:

1 app.get('/hello/:name', function(req, res) {
2   res.json({
3     hello: req.params.name
4   });
5 });

你将可以看到 nodemon 检测到文件的更改并重启了服务:

现在访问:http://localhost:3000/hello/world,你将会看到的页面:

Production

容器当前的状态,还远没有成型。redis 里面的数据在容器重启后会丢失。同样的,如果删掉这个容器重新生成一个,之前的数据也不会被保存。这样的结果是不乐观的,那么,在接下来的第二章,我会讲解产品的设置并解决这一问题。

   
次浏览       
 
相关文章

云计算的架构
对云计算服务模型
云计算核心技术剖析
了解云计算的漏洞
 
相关文档

云计算简介
云计算简介与云安全
下一代网络计算--云计算
软浅析云计算
 
相关课程

云计算原理与应用
云计算应用与开发
CMMI体系与实践
基于CMMI标准的软件质量保证
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件的思考
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS
更多...   
相关培训课程

云计算原理与应用
Windows Azure 云计算应用

摩托罗拉 云平台的构建与应用
通用公司GE Docker原理与实践
某研发中心 Openstack实践
知名电子公司 云平台架构与应用
某电力行业 基于云平台构建云服务
云计算与Windows Azure培训
北京 云计算原理与应用