Docker是如今開發應用程序的不錯選擇;由於對於一個研發組來講,部署一個應用不再用像之前那樣繁瑣的修改、設置配置文件了;由於對於Docker來講它「屏蔽」了應用程序的運行環境,無論你使用Mac、Linux仍是Windows都能用相同的方式運行。前端
可是,當你使用Docker將應用部署到生產環境時,你會以爲Docker仍是有些「弱」,至少從Ruby On Rails(ROR)的角度出發是這樣的。當我查找與測試了不少不一樣的部署方法與Docker鏡像後發現:確實沒有一個確切並且標準的部署方案。在這篇文章中我會分享一種生產環境部署ROR應用的最佳實踐。linux
標準web
在實際操做以前,咱們列舉生產環境部署應用的標準:sql
## 操做就像以前我說過的,我但願部署過程越簡單越好。若是你看過Docker:Part4這個視頻,可能對如下命令有所熟悉,它啓動了一個叫db的容器(跑postgres數據庫),以後又啓動了一個叫web的容器,最後將容器「web」跟容器「db」鏈接起來。docker
$ docker run -d --name db training/postgres $ docker run -i -t --name web --link db:db -p 45000:80
固然若是你照着這麼作來部署程序,當你敲了不少次這樣的命令後,並且保證不遺漏的敲了不少次這種命令後,你會發現這是個「坑爹的」噩夢。這就是爲何會有Fig的緣由。數據庫
FIG服務器
若是你用Dockerfile來定義如何生成你的容器,那麼Fig則能夠幫你定義整個容器的運行框架。Fig將「添加數據卷(add volumes)」、「鏈接容器」(link container)與「映射端口」等操做都封裝到一個YAML的描述文件中;如同前面提到的CodeTV中描述的那個操做在Fig中簡化成以下形式:負載均衡
web: build: . ports: - "80:80" links: - db db: image: postgres ports: - "5432" volumes: - /etc/postgresql - /var/log/postgresql - /var/lib/postgresql
我在YAML中定義了兩個容器:web與db;容器web生成自當前文件夾下的Dockerfile,向外暴露了80號端口,同時連接到了容器db。容器db生成自DockerHub的PostgreSQL鏡像,向外暴露5432號端口。使用此YAML配置文件,fig能夠用如下命令生成容器,而後依照配置文件的意圖啓動它們。框架
$ fig build $ fig up -d
Fig會先啓動被連接的容器db,這樣容器web就不至於連不上數據庫。-d參數表示之後臺運行的方式啓動容器,這樣能夠保證用戶登出操做系統後,容器任然在運行。您能夠登陸Fig的官方網站獲取更多的配置信息。工具
部署
如今咱們能夠很容易的啓動一個Docker容器,可是怎麼在生產環境下部署Docker容器呢?若是在生產環境下安裝了Fig與Docker,咱們全部要作的就是克隆以前的容器鏡像,而後用相同的fig命令來啓動容器。可是,如今的問題是如何更新線上運行的容器。
不幸的是,Fig能夠很是優雅的啓動一個容器,可是它並不擅長更新並重啓服務。固然,你能夠在代碼倉庫拉取程序的更新,而後從新運行以上的fig命令來達到這個目的;可是,在容器在更新代碼,從新啓動的過程當中,就不能對外提供服務了。爲了應對這種狀況,咱們使用原生的Docker命令,並引入Nginx作反向代理(注:軟負載)來解決這個問題。
咱們首先把容器監聽的端口修改掉,由於Nginx須要監聽80號端口。咱們這麼修改:
web: build: . ports: - "8080:80" links: - db ...
經過修改Fig的配置文件,咱們的web容器修改爲監聽8080號端口。而Nginx要配置成8080與8081端口的負載均衡;因此Nginx的配置以下:
upstream docker { server 127.0.0.1:8080; server 127.0.0.1:8081; } server { listen 80; location / { proxy_pass http://docker; } }
重啓Nginx後,Nginx就開始在8080與8081號端口之間作反向代理(軟負載);當其中任何一個端口失效後,Nginx將請求自動轉發到另外一個,直到失效後的端口恢復。這樣,咱們就能從Git中拉取更新,而後運行下面的命令將其啓動:
$ docker run -d --name web1 --link codetvjournal_db_1:db -p 8081:80 codetvjournal_web:latest
當咱們肯定8081號端口的web1容器啓動並服務正常後,咱們就能夠中止8080號端口的服務並開始爲8080號端口服務進行更新了。我推薦使用原生的docker命令而不使用Fig來完成這個工做,由於這樣能夠避免干擾到正在運行的db容器(注:做者可能指的是以前寫好的YAML,裏面包含了啓動db容器的配置)
咱們能夠用上述方法建立不少個web容器,只要保證它們佔用的端口與容器名不一樣便可;同時使用Nginx在它們前端作負載便可實現不掉線的程序升級。
自動化
那麼問題又來了,怎麼將上述的更新流程自動化運行呢?有兩個方式能夠達到:
因此,使用Docker在生產環境中部署服務不像你想象中那麼容易。我推薦你們試試上面所說的方法;同時分享你本身的實踐經驗給你們,這會幫助你們一同使用Docker。Docker仍是個很年輕的產品,同時又是個很是熱門的產品,它確定會在將來不斷的演化升級。
免費提供最新Linux技術教程書籍,爲開源技術愛好者努力作得更多更好:http://www.linuxprobe.com/