英文版原文地址node
這是兩篇連載文章的第一篇,講解了如何使用 Docker
替代 Vagrant 開發基於 Express
框架的NodeJs App的部分細節。不過,此次要增長點難度:咱們要使用 connect-redis 在 Redis 中實現 session 功能。第二篇文章將基於此繼續。python
這個 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
爲了便於開發,咱們會把 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-server
,Redis
服務是必需的,由於咱們要把 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.
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
成功運行了命令,情景應該以下圖:
容器如今已經運行起來了,不過,在開始編寫代碼以前,須要將一些標配的,非 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
,你將會看到的頁面:
容器當前的狀態,還遠沒有成型。redis
裏面的數據在容器重啓後會丟失。一樣的,若是刪掉這個容器從新生成一個,以前的數據也不會被保存。這樣的結果是不樂觀的,那麼,在接下來的第二章,我會講解產品的設置並解決這一問題。