docker部署webapp的例子

本文以 [tcl-tennis](https://github.com/limijiaoyin/tcl-tennis) 爲例,說明部署 Node.js webapp 的步驟。 javascript

## 建立 Dockerfile html

首先,clone 代碼 java

```sh
$ git clone git@github.com:limijiaoyin/tcl-tennis.git
``` node

根據 Docker 官網的幫助文檔 [Dockerizing a Node.js web app](https://docs.docker.com/examples/nodejs_web_app/),建立 Dockerfile: python

```Dockerfile
FROM    centos:centos6 git

# Enable EPEL for Node.js
RUN     rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
# Install Node.js and npm
RUN     yum install -y npm
RUN     yum install -y git github

# Bundle app source
COPY . /src web

# Install bower
RUN npm install -g bower --registry=http://registry.npm.taobao.org mongodb

# Install app dependencies
RUN cd /src; npm install --production --registry=http://registry.npm.taobao.org
RUN cd /src; bower install --allow-root docker

EXPOSE  12580
WORKDIR /src
CMD ["node", "app.js"]
```

__注意修改執行的 js 文件和暴露的端口。__

## 修改代碼,分離外部服務

不少的 webapp 都使用了DB、緩存、事件隊列等外部服務,因此須要事先確認系統是否已經安裝好了,若是沒有的話須要先安裝。目前系統當中預先安裝的服務列表在 [這兒]() 。

底層服務配置好以後,還要注意:不少的項目在工程配置方面都支持的不夠好,不少外部服務的地址和配置參數都是直接硬編碼到代碼當中的。使用 Docker 構建以前,須要修改代碼以支持各類配置的靈活修改。這樣纔可以好的運用 Docker。

以 tcl-tennis 爲例,服務器端使用了 mongodb,須要把遊戲成績存到 mongodb 的 `tennis` 數據裏面去,原來的代碼以下:

```javascript
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/tennis');
...
```

mongodb 的 `hostname` 被寫死成了 localhost,須要修改。分離各類外部服務的方法:[在環境中存儲配置](http://12factor.net/zh_cn/config),原文:

> __推薦將應用的配置存儲於 *環境變量* 中( env vars, env )。__環境變量能夠很是方便地在不一樣的部署間作修改,卻不動一行代碼... 

修改過的代碼以下:

```javascript
var mongodb_host = process.env.mongodb_host || 'localhost';
var mongoose = require('mongoose');
mongoose.connect('mongodb://' + mongodb_host + '/tennis');
...
```

## 構建鏡像,啓動服務

修改完代碼以後,就能夠開始構建鏡像了。首先,使用 [Daocloud.io](http://help.daocloud.io/intro/accelerator.html) 的加速器拉取 base 鏡像(Docker 默認會直接從他的鏡像源下載鏡像,可是網速實在太慢):

```sh
$ dao pull centos:centos6
```

而後構建鏡像:

```sh
$ docker build -t limijiaoyin/portfolio-tcl-tennis .
```

構建成功以後,能夠先試運行一下:

```sh
$ docker run \
 --rm \
 -it \
 -p 12580:12580 \
 --link mongo \
 --env mongodb_host=mongo \
 limijiaoyin/portfolio-tcl-tennis
```

使用 `--rm` flag 能夠在服務被關閉的時候自動幫咱們清理 container,很是適合調試鏡像。`-p` 用來設置 container 與主機之間的端口映射。使用 `--link` flag 將咱們的 webapp 和其餘服務鏈接起來。

一切都測試 OK 以後,設置服務在後臺運行。

```sh
$ docker run \
 -p 12580:12580 -d \
 --link mongo \
 --env mongodb_host=mongo \
 --restart=always \
 --name tcl-tennis \
 limijiaoyin/portfolio-tcl-tennis
```


`--restart` 用來設置重啓方式,`always` 表示不管任何狀況下,應用結束都會自動重啓。`--name` 用來設置 container 名稱。

## 總結

使用 Docker 部署 webapp 的通常步驟:

* 建立 Dockerfile
* __修改代碼,分離外部服務__
* 構建鏡像並調試
* 啓動服務後臺執行,設置自動重啓等
* 將修改的代碼從新提交到 git 代碼庫

## docker,uwsgi部署django應用須要注意的地方

* docker 內部的socket host 要用0.0.0.0,而不是127.0.0.1或localhost
* 靜態文件須要單獨處理,目前的方案是使用[whitenoise](https://pypi.python.org/pypi/whitenoise)


Docker 詳細的使用方法請參考 [官方文檔](https://docs.docker.com/userguide/)

相關文章
相關標籤/搜索