在CoreOS上启动node.js的方法备忘录
关于此帖内容
我大约用了一年的时间接触Docker,才意识到自己几乎没有使用过CoreOS。所以我写了这篇个人笔记,记录了使用CoreOS在Docker上运行GitHub上注册的Web应用程序的过程。我并没有做什么奇怪的事情(至少我觉得没有)。我在MacOS X上使用了VMWare Fusion7来进行操作,但我认为在其他环境下几乎可以复现相同的步骤。
CoreOS是什么?
CoreOS是专为使用Docker而设计的一种Linux发行版之一。它不考虑其他用途,非常轻量化是其优点。目前的版本是CoreOS 494.0.0。
CoreOS的安装方式
在CoreOS中,有多种安装方式可供选择。包括裸机,云服务(如Amazon EC2,DigitalOcean,Rackspace,Azure,Google Compute Engine),虚拟计算机环境(如Vagrant,VMWare,QEMU,Openstack,Eucalyptus)等等。
通常情况下,在介绍文章中,我们会看到很多使用Vagrant或云服务来启动CoreOS的示例,所以在这里,我们想尝试使用VMWare。但请注意,VMware不是官方支持的平台,而是社区支持的平台。请参阅文档以获取详细信息。
CoreOS的安装和启动
在VMware上运行CoreOS的方法,在”在VMware上运行CoreOS”的指南中有所介绍。基本上,只有alpha或beta版本的CoreOS可供使用。
$ curl -LO http://alpha.release.core-os.net/amd64-usr/current/coreos_production_vmware_insecure.zip
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 190M 100 190M 0 0 8433k 0 0:00:23 0:00:23 --:--:-- 16.3M
$ unzip coreos_production_vmware_insecure.zip -d coreos_production_vmware_insecure
Archive: coreos_production_vmware_insecure.zip
inflating: coreos_production_vmware_insecure/coreos_production_vmware_insecure_image.vmdk
inflating: coreos_production_vmware_insecure/coreos_production_vmware_insecure.vmx
inflating: coreos_production_vmware_insecure/insecure_ssh_key
$ cd coreos_production_vmware_insecure
$ ls
coreos_production_vmware_insecure.vmx
coreos_production_vmware_insecure_image.vmdk
insecure_ssh_key
在上述步骤完成安装后。接下来启动CoreOS,在VMWare的控制台上按下Enter键试试看。应该会显示ssh的密钥和IP地址。在我的情况下,显示的是172.16.11.136,所以我们尝试用ssh登录到这个地址上。
当尝试用ssh连接时,会显示密钥并询问“是否继续连接?”请输入yes。然后,提示符会变化,表明已成功登录。
$ open coreos_production_vmware_insecure.vmx
$ ssh -i insecure_ssh_key core@172.16.11.136
The authenticity of host '172.16.11.136 (172.16.11.136)' can't be established.
RSA key fingerprint is f7:a4:40:7b:8e:2c:c0:29:30:6e:77:af:21:ee:aa:fa.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.11.136' (RSA) to the list of known hosts.
CoreOS (alpha)
core@localhost ~ $
在Docker上安装Web应用
一旦到这一步,只需要启动Docker并大力使用就可以了。尽管如此,我认为初学者可能会不知道该做什么而感到茫然,所以我们在这里选择用node.js来尝试一下。
首先,我们要找到要使用的Docker镜像。你可以随便创建一个,但是这次我们打算从Docker Hub搜索一下。打开Docker Hub之后,会显示搜索框和官方仓库。正好有node.js的官方仓库,所以我们选择使用它。
打开该页面后,会提供各种版本的镜像。大致分为0.10系列,0.11系列和0.8系列版本,分别有原始版本,onbuild版本和slim版本。
Supported tags and respective Dockerfile links
・0.10.33, 0.10, 0, latest (0.10/Dockerfile)
・0.10.33-onbuild, 0.10-onbuild, 0-onbuild, onbuild (0.10/onbuild/Dockerfile)
・0.10.33-slim, 0.10-slim, 0-slim, slim (0.10/slim/Dockerfile)
・0.11.14, 0.11 (0.11/Dockerfile)
・0.11.14-onbuild, 0.11-onbuild (0.11/onbuild/Dockerfile)
・0.11.14-slim, 0.11-slim (0.11/slim/Dockerfile)
・0.8.28, 0.8 (0.8/Dockerfile)
・0.8.28-onbuild, 0.8-onbuild (0.8/onbuild/Dockerfile)
・0.8.28-slim, 0.8-slim (0.8/slim/Dockerfile)
在检查了每个Dockerfile的内容之后,可以大致地说发现了以下的差异。
◆無印=素の状態のOSに必要最低限のパッケージを追加してnode.jsをインストールする
◆onbuild=無印をベースにして,同じディレクトリに有るpackage.jsonなどをコピーして起動する
◆slim=素の状態のOSに必要最低限+αのパッケージを追加してnode.jsをインストールする
在这里,我们将使用0.10.33的onbuild版,快速启动一个基于node.js的Web应用程序。可以使用任何Web应用程序,但在这里我们将使用amirrajan/nodejs-chat。
以下是步骤:
1. 获取nodejs-chat
2. 确认启动脚本的文件名(日志中省略)
3. 确认启动脚本使用的端口号(日志中省略)
4. 创建Dockerfile(写入第3步中查询到的端口号)
5. 创建Docker镜像
6. 启动nodejs-chat
7. 从Web浏览器连接(参见下一节)
core@localhost ~ $ git clone https://github.com/amirrajan/nodejs-chat.git
Cloning into 'nodejs-chat'...
remote: Counting objects: 31, done.
remote: Total 31 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (31/31), done.
Checking connectivity... done.
core@localhost ~ $ cd nodejs-chat
core@localhost ~/nodejs-chat $ cat > Dockerfile
FROM node:0.10-onbuild
EXPOSE 3000
^D
core@localhost ~/nodejs-chat $ docker build -t nodechat .
Sending build context to Docker daemon 745.5 kB
Sending build context to Docker daemon
Step 0 : FROM node:0.10-onbuild
node:0.10-onbuild: The image you are pulling has been verified
36fd425d7d8a: Pull complete
aaabd2b41e22: Pull complete
3c20e07c38ce: Pull complete
b6ef456c239c: Pull complete
b045b0cd49ad: Pull complete
210d9bc26f2f: Pull complete
27ecce8bd36c: Pull complete
fcac83abd52d: Pull complete
edc7d098628f: Pull complete
b5ac041b53f9: Pull complete
387247331d9c: Pull complete
2080990fe5fe: Pull complete
04b1a9d3a23d: Pull complete
c0555bd85c9e: Pull complete
7e80806406ad: Pull complete
1c53475b3cc2: Pull complete
c6c4351d1205: Pull complete
511136ea3c5a: Pull complete
Status: Downloaded newer image for node:0.10-onbuild
# Executing 3 build triggers
Trigger 0, COPY package.json /usr/src/app/
Step 0 : COPY package.json /usr/src/app/
Trigger 1, RUN npm install
Step 0 : RUN npm install
---> Running in 722777567e74
npm WARN package.json nodejs-chat@0.0.4-21 No README data
> ws@0.4.32 install /usr/src/app/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws
> (node-gyp rebuild 2> builderror.log) || (exit 0)
make: Entering directory '/usr/src/app/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build'
CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
SOLINK_MODULE(target) Release/obj.target/bufferutil.node
SOLINK_MODULE(target) Release/obj.target/bufferutil.node: Finished
COPY Release/bufferutil.node
CXX(target) Release/obj.target/validation/src/validation.o
SOLINK_MODULE(target) Release/obj.target/validation.node
SOLINK_MODULE(target) Release/obj.target/validation.node: Finished
COPY Release/validation.node
make: Leaving directory '/usr/src/app/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build'
underscore@1.5.2 node_modules/underscore
ejs@0.8.8 node_modules/ejs
express@3.0.6 node_modules/express
├── methods@0.0.1
├── fresh@0.1.0
├── range-parser@0.0.4
├── cookie-signature@0.0.1
├── buffer-crc32@0.1.1
├── cookie@0.0.5
├── commander@0.6.1
├── mkdirp@0.3.3
├── debug@2.1.0 (ms@0.6.2)
├── send@0.1.0 (mime@1.2.6)
└── connect@2.7.2 (pause@0.0.1, bytes@0.1.0, formidable@1.0.11, qs@0.5.1)
socket.io@0.9.17 node_modules/socket.io
├── base64id@0.1.0
├── policyfile@0.0.4
├── redis@0.7.3
└── socket.io-client@0.9.16 (xmlhttprequest@1.4.2, uglify-js@1.2.5, active-x-obfuscator@0.0.1, ws@0.4.32)
Trigger 2, COPY . /usr/src/app
Step 0 : COPY . /usr/src/app
---> c6edcf3d1bcc
Removing intermediate container e26d4efe3918
Removing intermediate container 722777567e74
Removing intermediate container 1d7d9794350d
Step 1 : EXPOSE 8888
---> Running in f8bd71610ef6
---> 5cac1f68e77e
Removing intermediate container f8bd71610ef6
Successfully built 5cac1f68e77e
core@localhost ~/nodejs-chat $
Web应用程序的启动
根据nodejs-chat的server.js文件,可以确定它将使用3000端口。因此,在Dockerfile中,我们要通过使用EXPOSE命令声明使得容器外部也能使用3000端口。最后,在启动时要使用”-p 3000:3000″来将容器内的3000端口映射到容器外部的3000端口。此外,“–rm”是一个选项,它会自动删除已执行完成的容器。
完成上述步骤后,nodejs-chat就会启动,然后我们可以从Web浏览器进行连接。
我们可以使用CoreOS的IP地址和端口号,在浏览器中访问”http://172.16.11.136:3000/”。
如果连接成功,那么将会不断地输出以下类似的日志到控制台。
core@localhost ~/nodejs-chat $ docker run -p 3000:3000 --rm --name nodechat nodechat
> nodejs-chat@0.0.4-21 start /usr/src/app
> node server.js
info: socket.io started
debug: served static content /socket.io.js
debug: client authorized
info: handshake authorized FkslWD_gYHxyQD859UFZ
debug: setting request GET /socket.io/1/websocket/FkslWD_gYHxyQD859UFZ
debug: set heartbeat interval for client FkslWD_gYHxyQD859UFZ
debug: client authorized for
debug: websocket writing 1::
debug: websocket writing 5:::{"name":"servernotification","args":[{"connected":true,"to_self":true,"username":"Andy Williams"}]}
debug: broadcasting packet
debug: websocket writing 5:::{"name":"updateusers","args":[{"Andy Williams":"Andy Williams"}]}
・・・以下ログが延々と吐出される・・・
总结
在过去的一年中,Docker的环境快速发展,虽然一度被认为在实际应用环境中还有很多问题需要解决,然而最近开始逐渐消除導入上的障碍。预计未来,Docker的应用范围将进一步扩大。希望这篇文章能对那些想要尝试使用但不知从何入手的人有所帮助。