使用Docker開發NodeJs APP

英文版原文地址node

 

這是兩篇連載文章的第一篇,講解了如何使用 Docker 替代 Vagrant 開發基於 Express 框架的NodeJs App的部分細節。不過,此次要增長點難度:咱們要使用 connect-redis 在 Redis 中實現 session 功能。第二篇文章將基於此繼續。python

 

The Node App

這個 App 由一個 package.json , server.js 和 .gitignore 文件組成,就這麼簡簡單單:linux

.gitignore :git

1  node_modules/*

package.json :github

 1 {
 2      "name": "docker-dev", 
 3      "version": "0.1.0", 
 4      "description": "Docker Dev", 
 5      "dependencies": { 
 6          "connect-redis": "~1.4.5", 
 7          "express": "~3.3.3", 
 8          "hiredis": "~0.1.15", 
 9          "redis": "~0.8.4" 
10      } 
11  }

server.js :redis

 1 var express = require('express'),
 2     app = express(),
 3     redis = require('redis'),
 4     RedisStore = require('connect-redis')(express),
 5     server = require('http').createServer(app);
 6 
 7 app.configure(function() {
 8   app.use(express.cookieParser('keyboard-cat'));
 9   app.use(express.session({
10         store: new RedisStore({
11             host: process.env.REDIS_HOST || 'localhost',
12             port: process.env.REDIS_PORT || 6379,
13             db: process.env.REDIS_DB || 0
14         }),
15         cookie: {
16             expires: false,
17             maxAge: 30 * 24 * 60 * 60 * 1000
18         }
19     }));
20 });
21 
22 app.get('/', function(req, res) {
23   res.json({
24     status: "ok"
25   });
26 });
27 
28 var port = process.env.HTTP_PORT || 3000;
29 server.listen(port);
30 console.log('Listening on port ' + port);

Server.js 處理了依賴關係並啓動了一個Express App,這個Express App 配置了 Redis 裏存儲的 Session 信息並曝露了一個端點(endpoint)用來返回標準 json 格式的服務器狀態信息。sql

這裏須要稍微注意的是,Redis 的鏈接信息會被使用的環境變量所覆蓋--後面發佈時會有用到這一信息。docker

 

The Dockerfile

 

爲了便於開發,咱們會把 redis 和 node 運行在同一個容器裏,要實現這點,就必須用 Dockerfile 來配置容器 :shell

Dockerfile :express

 1 FROM dockerfile/ubuntu
 2 
 3 MAINTAINER Abhinav Ajgaonkar <abhinav316@gmail.com>
 4 
 5 # Install Redis
 6 RUN   \
 7   apt-get -y -qq install python redis-server
 8 
 9 # Install Node
10 RUN   \
11   cd /opt && \
12   wget http://nodejs.org/dist/v0.10.28/node-v0.10.28-linux-x64.tar.gz && \
13   tar -xzf node-v0.10.28-linux-x64.tar.gz && \
14   mv node-v0.10.28-linux-x64 node && \
15   cd /usr/local/bin && \
16   ln -s /opt/node/bin/* . && \
17   rm -f /opt/node-v0.10.28-linux-x64.tar.gz
18 
19 # Set the working directory
20 WORKDIR   /src
21 
22 CMD ["/bin/bash"]

讓咱們逐行逐行來看看 Docherfile 裏的代碼:

1 FROM dockerfile/ubuntu

告訴 Docker 用 Docker 公司提供的 dockerfile/ubuntu 的鏡像文件做爲 build 時的基礎鏡像。

1 RUN  \
2   apt-get -y -qq install python redis-server

基礎鏡像自己並無任何東西,因此,咱們須要用 apt-get 命令將所須要的組件打包進去。這條表示安裝 python和 redis-serverRedis 服務是必需的,由於咱們要把 session 信息存儲進去。對於 npm 而言,python 能夠爲 Redis Node 生成 C 擴展。

1 RUN  \
2   cd /opt && \
3   wget http://nodejs.org/dist/v0.10.28/node-v0.10.28-linux-x64.tar.gz && \
4   tar -xzf node-v0.10.28-linux-x64.tar.gz && \
5   mv node-v0.10.28-linux-x64 node && \
6   cd /usr/local/bin && \
7   ln -s /opt/node/bin/* . && \
8   rm -f /opt/node-v0.10.28-linux-x64.tar.gz

下載並解壓 64 位二進制版 NodeJs

1 WORKDIR  /src

這句話是告訴 Docker -- 容器開始運行時進入 cd /src 目錄。

1 CMD ["/bin/bash"]

此爲最後一步:啓動 /bin/bash.

 

Build and run the container

Docker file 配置好後,咱們來生成一個 Docker 鏡像:

1 docker build -t sqldump/docker-dev:0.1 .

生成成功後,就能夠用下面的命令啓動容器了:

1 docker run -i -t --rm \
2            -p 3000:3000 \
3            -v `pwd`:/src \
4            sqldump/docker-dev:0.1

咱們來分析一下這個命令。

-i: 以交互模式運行容器 (不一樣於 -d : 以分離模式運行容器),這意味着交互回話 session 結束時,容器就會中止運行。

-t : 分配了一個虛擬終端pseudo-tty

--rm : 中止運行時移除容器和文件系統。

-p 3000:3000 :主機端口 3000 : 容器端口 3000

1 -v `pwd`:/src

這條命令把主機的當前工做目錄(如,項目文件)載入容器的/src裏面。咱們載入文件而不是使用 add 命令增長文件,這使得咱們在文本編輯器裏更愛文件後能馬上在容器裏看到效果。

sqldump/docker-dev:0.1 : 當前運行的 docker 鏡像的名字和版本號與咱們生成的鏡像是同樣的。

因爲 Dockerfiles 指定了 CMD ["/bin/bash"],容器運行後咱們就進入了一個 bash shell。若是 docker 成功運行了命令,情景應該以下圖:

 

 

Start Developing

容器如今已經運行起來了,不過,在開始編寫代碼以前,須要將一些標配的,非 docker 文件分別安裝。首先,用以下命令在容器裏啓動 redis 服務:

1 service redis-server start

而後,安裝相關依賴和 nodemon 。Nodemon 能夠實時監聽項目文件的變化並重啓服務。

1 npm install
2 npm install -g nodemon

最後,用以下命令啓動服務:

1 nodemon server.js

如今,打開你的瀏覽器並訪問:http://localhost:3000,順利的話會出現下圖情景:

給 server.js 增長一個端點以模擬開發工做流:

1 app.get('/hello/:name', function(req, res) {
2   res.json({
3     hello: req.params.name
4   });
5 });

你將能夠看到 nodemon 檢測到文件的更改並重啓了服務:

 

如今訪問:http://localhost:3000/hello/world,你將會看到的頁面:

 

Production

容器當前的狀態,還遠沒有成型。redis 裏面的數據在容器重啓後會丟失。一樣的,若是刪掉這個容器從新生成一個,以前的數據也不會被保存。這樣的結果是不樂觀的,那麼,在接下來的第二章,我會講解產品的設置並解決這一問題。

相關文章
相關標籤/搜索