打包node.js应用成为docker image

转自: https://www.douban.com/note/321815809/

其实node.js的部署并不是什么特别大的问题,有nvm,有npm,多数情况下其实部署并不是什么令人感到头痛的问题。

实体机上的部署可以参考:
1、node.js部署最佳实践
http://www.douban.com/note/265207425/

2、forever结合chkconfig将网站启动和关闭都开机自服务化
http://www.douban.com/note/318448663/

3、mean.io的BUG
http://www.douban.com/note/318584640/

============================================
但是如果想做到稍稍自动化一些,docker可能是最近的一个比较好的选择。

那么思路上来说,将你的node.js app打包成docker的image的手工步骤应该分解成几步呢?

1、创建一个最小的裸image
2、安装必要的依赖,比如g++
3、安装node.js本身,并且要选择好版本,必要时可以使用nvm
4、将app的裸代码拷贝的建立的image当中去
5、运行npm install加载依赖(在这之前可以修改npm的repos为http模式,加快速度)
6、运行必要的自动化测试并报告结果
7、按照某种约定暴露该服务的端口号给host机
8、使用pm2或者是forever将该app服务化,并配置为开机启动
9、调整express等模块的运行模式,生产模式或其它
10、复杂的项目如果依赖JAVA,那么自动化部署java到image就是第一步了
11、导出刚才的那个image为打包文件?

see,很简单吧?

好吧。。。。。。。。。。。。

==========================================

看来主要要从Dockfile入手了,说起来就像Makefile一样简单的东西,不是么

OK,让我们来看看有没有现成的项目

https://github.com/adamalex/docker-urlarchiver/blob/master/Dockerfile
http://oskarhane.com/create-a-nodejs-docker-io-image/

OK,抽出共性

得到第一版本的Dockfile就是

#从12.10开始搞
FROM ubuntu:12.10

#这里改成自己的
MAINTAINER lemonhall, lemonhall@gmail.com

#升级系统本身
RUN apt-get update && apt-get upgrade

#搞定大多数的c和c++模块所需要的东西(不过这容易让image变得很大)
RUN apt-get install python-software-properties python g++ make software-properties-common

#OK,加入node的二进制包仓库,我们并不想从源码编译
RUN add-apt-repository ppa:chris-lea/node.js && apt-get update

#安装 node.js
RUN apt-get install nodejs

==============================
将host机器上的项目首先打包好

tar zc --exclude node_modules --exclude .git -f app.tar.gz app

--exclude命令不打包node_modules和.git,这样压缩包的大小会非常小

然后
Dockfile里面开始添加用户:
RUN useradd -m -d /home/node node
RUN usermod -a -G nobody node

接下来拷贝必要文件到虚拟机里:(这里需要变量化)
ADD app.tar.gz /home/node/
RUN su node
RUN cd /home/node/
RUN tar zxf app.tar.gz
RUN cd app
RUN npm install

===============================================
解析来的事情又需要ROOT权限了:
RUN npm install forever -g

       a)在/etc/rc.d/init.d里面加上app这个文件
       b)chmod +x app #使得文件可运行
       c)chkconfig --add app #用这个命令来加入新的服务

app这个脚本文件可能需要代码来生成,将某些变量加入进去,另外如果是express的项目,还得然该用户可以选择是否将环境变量先设置为生产模式

【NODE_ENV=production】

#!/bin/bash
# chkconfig: 2345 70 30
# description: app service
# processname: app #第一个进程名,后边设置自启动的时候会用到
PATH=/usr/local/bin/

start() {
echo "Starting app ..."
        forever start /home/node/app/server.js
}

stop() {
        echo "Stopping mean ..."
        forever stop /home/node/app/server.js
}

# See how we were called.
case "$1" in
  start)
start
;;
  stop)
stop
;;
  restart|force-reload)
stop
start
;;
  *)
echo $"Usage: $0 {start|stop|restart|force-reload}"
exit 2
esac

======================================
以上脚本存在几个问题:
1、如果可以,最好还是将forever生成的log暴露给宿主机,这样可以方便查看问题。
2、该脚本有一个注定的main.js的入口才可以,这个脚本的生成和修改看上去并不是那么自动化,比如如果项目依赖mongod等等,该怎样搞的事情,从中间配置服务器哪里读取某些依赖的配置项?
3、另外如果可以的话,应该是一条命令就可以出发目标image里面的service star和service stop这类的命令。
4、监控

posted @ 2016-04-18 10:45  杨博客  阅读(2598)  评论(0编辑  收藏  举报