在windows下部署nodejs开发环境着实遍地坑,每遇到一个问题都要去google缘由再试图解决。并且若是你想把你写好的应用交给别人跑跑看,他可能一样须要折腾好久才能真正在他的环境下运行起来。被坑了好些时日最终仍是放弃,转战Docker。node
Docker的简介不在本文赘述,基本概念可参看Docker——从入门到实践mysql
文章开头先明确一下咱们但愿实现的效果:git
依然在Windows下编辑源代码,在Docker容器中运行代码,最后在Windows的浏览器中看到运行结果,方便后续debug。github
能够将我开发完成的程序和运行环境一块儿打包制做成Docker的image,移交image给小伙伴运行或者直接发布到服务器上。web
Docker引擎核心是运行在Linux操做系统上的Linux容器。因此要在Windows上使用Docker容器,先要提供Linux运行环境。redis
去Docker官网下载msi安装程序,若你的系统版本(例如64bit Windows 10 Pro, Enterprise and Education)支持Hyper-V虚拟技术,那么不须要使用额外的虚拟机(VirtualBox),安装程序会自动为你安装完成Docker(Docker for Windows)。sql
The Hyper-V package must be enabled for Docker for Windows to work. The Docker for Windows installer will enable it for you, if needed. (This requires a reboot). If your system does not satisfy these requirements, you can install Docker Toolbox, which uses Oracle Virtual Box instead of Hyper-V.docker
若不能使用Hyper-V虚拟技术,Docker项目组也提供了Docker ToolBox工具,能够很方便的在Windows环境下安装Docker。npm
更详细内容参考Docker官方文档-toolbox。json
本文中的执行系统为Win7,故使用Docker toolbox。
安装过程会附带安装Oracle VM VirtualBox虚拟机,以下图:
Kitematic为Docker的GUI管理工具,打开Docker Terminal能够快速地启动Docker。
能够发现此时Docker给default machine分配了一个IP:192.168.99.100。咱们能够直接在该终端下执行Docker命令。
因为在Windows中运行Docker多加了一层虚拟机,有几个概念须要了解:
Docker主机指的是Linux虚拟机,也就是说,此时Docker主机(即Linux虚拟机)的IP地址为192.168.99.100。
与通常的ssh访问虚拟机同样,咱们也能够经过该IP用ssh登陆到Docker主机去执行命令。(用户名:docker;密码:tcuser)
如要用root权限去执行Linux命令(如mount),则须要打开VirtualBox。
新安装好的Docker主机中没有任何image(docker images
查看已有的image)。运行node应用须要搭建node环境镜像,能够从Docker Hub上pull轻量级的Linux镜像做为基础镜像(如CentOS),在上面手动安装node;也能够直接pull一个已安装了node的镜像(docker pull
拉取镜像)。从Docker Hub下载镜像可能很是慢,能够借助国内的云服务商下载(如daocloud.io)。
如今假设咱们pull了一个不包含node环境的CentOS镜像。
$ docker run -it centos bash
启动一个容器,并进入容器的bash进行交互式操做。采用与CentOS下同样的方式安装node。安装完成后exit
退出容器。请放心,若是不使用docker rm
或者docker run
时不增长--rm
参数,即便退出容器,容器自己及其中的修改不会消失。能够用docker ps -a
查看全部容器,docker ps
查看正在运行的容器。
$ docker commit <CONTAINER_ID> <IMAGE>
提交以前修改的容器到新的image。该镜像就是已经安装了node环境的镜像(命名为nodejs)。
在后续的开发中咱们能够用docker run -it nodejs bash
启动容器。
咱们如今须要在Docker容器中运行源代码,而Docker容器是在Docker主机中的,因此首先,咱们须要先保证Docker主机(即Linux虚拟机)能访问到Windows中的源代码文件。
打开VirtualBox,点击“设置”->“共享文件夹”,指定路径和名称后勾选“自动挂载”和“固定分配”。“自动挂载”可使得虚拟机下次启动时自动挂载文件夹,不然每次启动都须要从新手动挂载。
若是顺利,重启虚拟机输入mount
命令,能够看到共享文件夹挂载到了哪里,进入该目录就能看到与Windows下同步的文件。
若是自动挂载遇到问题,取消这个选项,使用如下命令手动挂载:
mount -t vboxsf docker_share <mount_point>
首先在Windows的共享文件夹下编辑测试代码app.js:
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(1337); console.log('Server running at http://0.0.0.0:1337/');
能够在Docker主机中看到该文件。
用nodejs镜像启动一个容器,咱们但愿这个容器能访问Docker主机中的文件做为源代码,还但愿能在Windows下访问运行后的执行端口查看结果。用如下命令启动容器:
$ docker run -v /docker_share:/app -p 1337:1337 -it nodejs bash
-v 主机目录:容器数据卷目录
使得主机目录被挂载到容器中,可被容器访问。-p 主机端口:容器端口
使得容器端口被映射到主机上,能够被容器外部访问到。
注: 重复多个-p命令能够映射多个端口。
(Docker 0.11版本以上可使用--net=host参数使得容器中的全部端口映射在Docker主机上。故也可以使用:)
$ docker run -v /docker_share:/app --net=host -it nodejs bash
进入容器中对应的数据卷目录,执行node app.js
Windows下经过浏览器访问192.168.99.100:1337可看到结果
至此,基本的node应用已经能在Docker下跑起来啦~
1. npm install
通常在node工程中都会存在node_modules依赖须要用npm install
安装。在Docker下,指望运行应用的容器中,一样能够执行该命令。但注意增长--no-bin-links
指令来避免建立软链接。
npm install --no-bin-links
2. 关联其余服务与容器互联
许多node应用都会关联启用redis、mysql等服务。直接地,咱们能够像在Windows下同样打开同一个容器的多个终端分别运行服务或执行代码。用如下命令进入一个正在运行的容器:
$ docker exec -it <CONTAINER> bash
更优雅地,咱们将不一样的服务运行在不一样的容器上,而后使用--link name:alias
容器互联的方式将他们关联起来,详情能够看这篇博客。
3. 实时响应代码变化
在开发过程当中,若是每次修改代码都须要结束node进程而后重启必然会很麻烦。可使用nodemon工具实现监控代码变化并自动重启进程的效果,这样一来只须要在浏览器下刷新就能够看到新的运行效果。
安装nodemon:
npm install -g nodemon
依然以app.js为例,在容器中运行app.js时使用命令:
nodemon -L app.js
注:若是不在容器下运行,使用nodemon app.js
便可,而在容器中,须要使用-L
或--legacy-watch
参数打开Chokidar轮询,才能监听到挂载目录中文件的改变。
尝试更改app.js内容,保存后能够发现nodemon自动重启了:
刷新浏览器看到修改后的结果:
关于nodemon,更详细的使用参见GitHub-nodemon。
在工程目录下编辑Dockerfile和.dockerignore文件。
Dockerfile:
FROM nodejs # Create app directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # Install app dependencies COPY package.json /usr/src/app/ RUN npm install # Bundle app source COPY . /usr/src/app EXPOSE 8080 CMD [ "npm", "start" ]
FROM
指定基础镜像,接下来列出基于基础镜像须要作的操做命令,搭建起新的Image环境(包括复制源码和执行npm install
)能够参考node官方文档和这篇博文。
.dockerignore:
node_modules npm-debug.log
在build新镜像时忽略其中的文件。
在Docker主机中的工程目录下(Dockerfile所在目录)使用命令:
$ docker build -t <ImageName> . //注意末尾的点不可省去
可获得自行build的镜像。该镜像会自动添加到你的docker主机下,你能够直接启动新镜像的容器运行代码(镜像内就包含代码,因此无需重复挂载到数据卷,不过就不能在Windows下修改了),也能够将镜像分享给小伙伴。
到此,应该已经能知足基本的开发需求。
虽然在Windows下使用Docker由于多加的一层虚拟机会以为有一点别扭,可是Docker自己用容器和镜像将开发环境封装隔离的特性依然带来诸多方便。
以上都是我初步接触Docker的折腾结果,若是有什么错误或者更方便的方式方法欢迎交流指正。