国产ThinkJS 项目构建 Docker 镜像制作与log日志问题

   很多朋友喜欢用nodejs语言编写服务器程序,因此国产thinkjs架构应用也比较广泛,使用 Docker 部署 ThinkJS 相关的项目,因此仍是拿出来讲说吧。须要提早说明的是本文并非 Docker 的基础教程,默认你们都是了解 Docker 的。为 ThinkJS 项目构建和部署过程当中可能须要注意的点,咱们先说说如何构建镜像,而后再说一下可能出现的问题。

构建镜像
基础镜像
FROM mhart/alpine-node:8.9.4
首先推荐你们基于 mhart/alpine-node 的镜像来构建,由于真的很小(20M左右)!不过由于小有不少的构建工具都不是很全,若是赶上一些安装时须要编译的模块时可能会缺乏环境,这个时候你能够选择手动去安装环境,固然也能够选择使用 Docker 官方的 library/node 镜像(800M左右),为了省事推荐这种状况下仍是使用后者比较好。前端

依赖安装
COPY package.json /animaris/package.json
RUN npm i --production --registry=https://registry.npm.taobao.org
选好了基础镜像以后下面就须要拷贝项目文件了。这里推荐你们先把 packge.json 文件 COPY 进来而后安装依赖。由于依赖的变化比较小,能够认为一段时间内这部分的镜像层都是稳定的。而项目代码会随着需求变动而常常变化。综上所述,咱们选择让不变的镜像层优先打包保证镜像层的最大可复用性。node

拷贝项目
一个正常的 ThinkJS 项目其实线上运行只须要如下几个文件:nginx

app/:项目原始码文件夹,若是是未编译项目的话对应的是 src/ 目录
view/:前端模板文件夹
www/:前端静态资源文件夹
production.js:ThinkJS 启动脚本
因此只要按照顺序把这些文件 COPY 进去就能够了。git

启动项目
你们日常都习惯使用 PM2 来启动 NodeJS 项目,它最大的好处就是可以帮咱们守护项目进程,当进程被杀死的时候能帮咱们自动重启。不过 Docker 自己就是有自动重启的特性的,因此在不少层面上 Docker 和 PM2 一块使用都有点冲突。其实由于 Docker 充当了守护的角色,咱们彻底能够直接使用 node production.js 命令去启动。如下是一个完整的 ThinkJS 项目 Dockerfile 示例:github

FROM mhart/alpine-node:8.9.4

WORKDIR /animaris
COPY package.json /animaris/package.json
RUN npm i --production --registry=https://registry.npm.taobao.org

COPY src /animaris/src
COPY view /animaris/view
COPY www /animaris/www
COPY production.js /animaris/production.js

ENV DOCKER=true
EXPOSE 8360
CMD [ "node", "/animaris/production.js" ]
使用以下命令进行构建:docker

docker build -t lizheming/animaris ./Dockerfile
以后使用以下命令运行镜像,便可使用 http://localhost:8360 访问网站:shell

docker run -p 8360:8360 lizheming/animaris
注意事项
本地文件
使用 Docker 必定不能忘记的特性就是容器销毁后容器内的全部资源都是会被销毁的,下回会从新初始化,因此若是是须要持久化保存的应避免写到容器中,须要选择外部的持久化存储,例如 Volume 共享卷或者 S3 等相关服务。npm

ThinkJS 项目启动后通常会有 logs, runtime 两个目录会写入文件。其中 logs 是用来存储线上日志用的,这个最好使用共享卷的形式外载出来,方便以后排查问题。runtime 这个是 ThinkJS 运行时临时文件的存储地方,例如 cache 和 session 等。session 会话默认是使用文件类型存储的,若是使用 Docker 的话推荐选择 MySQL 等外部存储。其它的功能有相关需求也能够参考 session 服务。固然若是懒得用直接把 runtime 共享卷出来也是能够的。json

还有就是若是有用户上传类的需求会上传到本地文件夹上也要记得共享出来,不然丢数据就完蛋叻!

静态资源
ThinkJS 一直主张在生产环境中使用 Nginx 来处理静态资源,这样不须要通过 Node 层直接 Server 转发性能会更高。不过这样就给镜像打包形成了必定的麻烦,由于静态资源也被打包到项目镜像里去了,而 Nginx 镜像正常是没办法跨镜像读取到文件的,因此就死解了。

在 ThinkJS 中是利用 think-resource 这个中间件来处理静态资源的访问的,而后它在线上环境的状态是 enabled: false。其实静态资源过一层 Node 并消耗不了多少资源,除非对性能有严苛要求的,我建议均可以直接把这个功能打开。这样全部的请求都统一成 Nginx 转发到 Node 镜像,解决了 Nginx 须要跨镜像读取文件的问题。具体可参考官方文档的“为何上线后静态资源访问不了?”

module.exports = [
...
{
handle: 'resource',
enable: true // 始终开启,默认为 enable: isDev 表示只再开发环境下开启
},
...
]
固然若是真的要在打包成一个镜像的状况下用 Nginx 处理静态资源也不是没有办法,咱们能够利用共享卷来操做。Node 镜像经过将镜像文件共享卷的形式映射到本地,而后 Nginx 镜像经过共享卷的形式将以前本地映射的文件再映射到镜像中。这样经过本地的一层转发便可实现 Nginx 的跨镜像访问静态资源。

ThinkJS 镜像

docker run
-v ./www:/app/www
-p 8360:8360
lizheming/animaris

Nginx 镜像

docker run
-v ./nginx.conf:/etc/nginx/conf.d/animaris.conf
-v ./www:/var/www/animaris/www
-p 80:80
nginx
server {
listen 80;
server_name animaris.eming.li;
root /var/www/animaris/www;

location ~ /static/ {
    etag         on;
    expires      max;
}

}
环境变量
日常咱们是使用 development.js 和 production.js 来区分开发环境和生产环境的,然鹅这么打包以后发现都是生产环境了。这样有时候咱们须要不一样环境不一样配置就不太好弄了。这里推荐你们使用环境变量来区分。

think.env = process.ENV.ENV;

docker run -e ENV=test -p 8360:8360 lizheming/animaris
终端日志
有用户提出疑问 #1106,说“网站500了为啥 logs 里没看到日志?”。这是由于虽然 ThinkJS 内部的日志都是用 think-logger 模块处理了,可是由于跨模块或者启动时机的问题,有一些日志没办法走日志模块记录并存储到文件,会直接打到终端里。因此当没有日志的时候咱们能够考虑去 docker logs 中捞一下终端的日志,说不定有意外的惊喜。

通过docker查看log日志
通过docker logs命令可以查看容器的日志。

命令格式:

$ docker logs [OPTIONS] CONTAINER
Options:
--details 显示更多的信息
-f, --follow 跟踪实时日志
--since string 显示自某个timestamp之后的日志,或相对时间,如42m(即42分钟)
--tail string 从日志末尾显示多少行日志, 默认是all
-t, --timestamps 显示时间戳
--until string 显示自某个timestamp之前的日志,或相对时间,如42m(即42分钟)
例子:

查看指定时间后的日志,只显示最后100行:

$ docker logs -f -t --since="2018-02-08" --tail=100 CONTAINER_ID
查看最近30分钟的日志:

$ docker logs --since 30m CONTAINER_ID
查看某时间之后的日志:

$ docker logs -t --since="2018-02-08T13:23:37" CONTAINER_ID
查看某时间段日志:

$ docker logs -t --since="2018-02-08T13:23:37" --until "2018-02-09T12:23:37" CONTAINER_ID

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容