英文版原文地址

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

The Node App

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

.gitignore :

  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 <abhinav316@gmail.com>

 # 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 时的基础镜像。

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

基础镜像本身并没有任何东西,所以,我们需要用 apt-get 命令将所需要的组件打包进去。这条表示安装 python和 redis-serverRedis 服务是必需的,因为我们要把 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

 WORKDIR  /src

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

 CMD ["/bin/bash"]

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

Build and run the container

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

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

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

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

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

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

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

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

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

 -v `pwd`:/src

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

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

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

Start Developing

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

 service redis-server start

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

 npm install
npm install -g nodemon

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

 nodemon server.js

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

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

 app.get('/hello/:name', function(req, res) {
res.json({
hello: req.params.name
});
});

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

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

Production

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

使用Docker开发NodeJs APP的更多相关文章

  1. nodejs docker 开发最好选择yarn 进行包管理而不是npm

    npm 与yarn 的区别网上一大堆的文章,我们在构建docker 镜像是应该遵守的有些原则   基础镜像尽量小 对于构建进行缓存处理 构建的docker 的文件层数尽量少 能直接运行的,就别进行重复 ...

  2. Visual Studio Code和Docker开发asp.net core和mysql应用

    Visual Studio Code和Docker开发asp.net core和mysql应用 .net猿遇到了小鲸鱼,觉得越来越兴奋.本来.net猿只是在透过家里那田子窗看外面的世界,但是看着海峡对 ...

  3. 【转载】用Ionic开发hybrid APP

    使用phonegap开发APP的优劣在此不必细说,快速,简单,跨平台,以及随着iOS,Android本身对webview优化所带来的不错的性能,便是其独有的优势.而且私以为在目前激烈而又变化快速的移动 ...

  4. Cordova+ionic 开发hybird App --- 开发环境搭建

    Cordova 开发hybird App 开发环境搭建 一.一些基础概念: Ant : 简单说来可以这么理解,如果你用记事本写JAVA程序,然后在cmd里输入javac命令编译它,但是有一天你发现每次 ...

  5. App开发到App Store上架,发布流程。

     http://blog.csdn.net/wojsg001/article/details/12005887 App开发到App Store上架,发布流程. 分类: IOS2013-09-25 11 ...

  6. 像asp.net Mvc一样开发nodejs+express Mvc站点

    像asp.net Mvc一样开发nodejs+express Mvc站点 首先,我是个c#码农.从事Mvc开发已然4个年头了,这两年前端MVC的兴起,我也跟风学了一些,对前端的框架也了解一些,angu ...

  7. 跨平台移动APP开发进阶(二)HTML5+、mui开发移动app教程

    前端开发APP,从HBuilder开始~ 序 通过 HTML5 开发移动App 时,会发现HTML5 很多能力不具备.为弥补HTML5 能力的不足,在W3C 中国的指导下成立了www.HTML5Plu ...

  8. 带你从零学ReactNative开发跨平台App开发(一)

    ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...

  9. nodeJS学习(8)--- WS/...开发 NodeJS 项目-节3 <使用 mongodb 完整实例过程>

    使用 mongodb 的小系统 参考:https://my.oschina.net/chenhao901007/blog/312367 1. Robomongo 创建项目的数据库和数据表 参考:htt ...

随机推荐

  1. div两侧的boder断开 消失 奇怪

    原文发布时间为:2009-11-06 -- 来源于本人的百度文章 [由搬家工具导入] 解决方法: 设定外层DIV的宽度即可,如 width:99% ========================== ...

  2. gridview行链接

    原文发布时间为:2009-04-21 -- 来源于本人的百度文章 [由搬家工具导入] 点击行,链接!! 可这样,在GridView的RowDataBound输入代码,假如id在第0列,且不是摸板列: ...

  3. 5种你未必知道的JS和CSS交互的方法

    随着浏览器不断的升级改进,CSS和JavaScript之间的界限越来越模糊.本来它们是负责着完全不同的功能,但最终,它们都属于网页前端技术,它们需要相互密切的合作.我们的网页中都有.js文件和.css ...

  4. [LeetCode] Climbing Stairs 斐波那契数列

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  5. Qualcomm MPM introduction

    在 Qualcomm chip 裡有一個 hardware block 名為 MPM. 在 RPM CPU halts 後,MPM 會保持在 on 的狀態用來處理 全系統 sleep process ...

  6. Day 26 python 正则表达式

    re模块\正则表达式 一.元字符 1.. ^ $ * + ? { } [ ] | ( ) \ "." 代表(任意一个字符) "*" 代表(任意数量任意字符,0- ...

  7. 使用Nginx+FFMPEG搭建HLS直播转码服务器

    目的:使Nginx支持Rtmp协议推流,并支持hls分发功能及FFMPEG转码多码率功能. 一.准备工作 模块:nginx-rtmp-module-master(支持rtmp协议) 下载地址: htt ...

  8. 【原创】Word2010 清除样式

    使用场景         有时候我们在网页上面粘贴一些精华文章或者从去整理别人已经完成的word的时候,会发现它自带的格式,可能并不是我们所理想的格式,所以此时就不得不去重新编辑其格式,但是word里 ...

  9. 在DB2中使用EXPORT实现将数据导出文本文件

    EXPORT TO "D:/test.txt" OF DEL SELECT loginname,password FROM cm_staff where loginname = ' ...

  10. [Python Debug] SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.

    I Got a SettingWithCopyWarning when I ran the following code: tmp=date[date['date'].isnull().values= ...