Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker + node 入门 #4

Open
xtx1130 opened this issue Oct 11, 2017 · 4 comments
Open

docker + node 入门 #4

xtx1130 opened this issue Oct 11, 2017 · 4 comments
Labels

Comments

@xtx1130
Copy link
Owner

xtx1130 commented Oct 11, 2017

最近试着把自己写的node服务用docker包裹起来。只是对docker的简单入门,docker熟练工可以直接撤了,日志有待改进,虽然网上有很多方案,但是感觉多了一层docker后,日志总是没有很好的解决方案

1.简介

之前做过一个代理转发的项目,同时试水过简单的docker test case,利用闲暇时间,整合了一下第一个项目和docker,这里主要讲其中踩到的坑和遇到过的问题。

2.dockerfile和程序设计

整体设计如下所示:
issue4-1

  • docker 的-p参数通过端口映射可以确保外部能访问到docker内部端口,而docker的默认启动方式中,会产生一块虚拟网卡,也可以和外界进行网络交互,具体细节这里不再深究请自行查证资料。这样,网络交互的问题就完美解决了。
  • 在设计docker和node的时候,决定中间加一层forever,因为日志没有实现很好,所以如果有问题的话,没有进程守护还是很麻烦的。
  • 日志主要是存在docker container中,通过forever 的日志系统实现的存储,所以这个弊端很明显,就是必须用docker exec来翻日志,还好我是本地用,对日志没有强烈的需求。日志的种类有很多,在这里我只列出来了error的日志,在测试docker的时候方便我查找问题。
forever start -a -e /usr/src/personal-proxy/logs/error_log.log /usr/src/personal-proxy/index.js $port
  • 可能大家会有疑问,为什么外层宿主机也挂了一层代理?这是和公司的业务架子相关的代理,没办法去掉,除非把公司的业务架子代理重构……最终是通过这层代理去发起外网的request以及response给client端。

3.开发过程中的调试

  • 对于docker调试还没有找到很好的办法,我在开发的时候,主要是通过在宿主机跑通整体流程,然后进行docker包裹、生成镜像、docker run的同时在另一个终端用doceker exec进入docker container进行调试。

4.调试过程中遇到的坑

  • 对docker进行调试的时候可能需要经常生成镜像,而在频繁生成镜像的过程中会产生很多 镜像,如图所示:
    issue4-2
    可见这些镜像多么占存储空间,在清理的时候,也花了一番功夫。最靠谱的办法就是:docker kill container,然后docker images 列出来所有的镜像,可以通过docker rmi来清除,当然也可以从网上拽个脚本下来,比如:
docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm 
  • docker run 指令在运行的时候监听的是dockerfile的CMD指令,如果你的CMD是shell文件就要稍微注意一下,当然,如果你CMD node的话是绝对ok的。但是我的程序里加入了一层forever,你懂得。如果CMD shell的话,要注意加上一句:tail -f /dev/null; 保证shell不会退出,这样才能保证docker正常运行。
  • 不要忘了.dockerignore 文件,尤其是node_modules,完全没必要放到镜像中,只需要在dockerfile中执行下npm install即可。
  • dockerfile中一定要注意写CMD,这是docker run的时候要监听的指令,RUN是代替不了CMD的,如果没写的话,docker是跑不起来的。
@xtx1130 xtx1130 added the nodejs label Oct 11, 2017
@shawn-msft
Copy link

如果没记错的话,Dockerfile里没写CMD,docker run的时候可以手动指定启动命令,比如docker run xxx:latest /bin/sh -c "node xxx.js"

@xtx1130
Copy link
Owner Author

xtx1130 commented Feb 24, 2018

@shawn-ye 恩,这个是没问题的,但是感觉跑起来的话command参数能在dockerfile中定义一般不会直接 docker run image [command]吧?我也是docker杂牌军,不太了解规范。。。如果有什么问题,还请斧正😆

@shawn-msft
Copy link

@xtx1130 谦虚了,我一般也用CMD写在image里面。只是在某些时候比如调试 可以用docker run后面的命令覆盖掉Dockerfile里面的。

@xtx1130
Copy link
Owner Author

xtx1130 commented Feb 24, 2018

@shawn-ye 哦哦,也就是 docker run [command]的优先级要高于CMD。这里真没注意过。之前在做这个项目的时候CMD命令很简单,也没仔细分析过docker run --help。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants