Dokku和Docker的完美配合,一起來辯

jopen 9年前發布 | 28K 次閱讀 Docker

本文作者介紹了如何在單機上將Dokku和Docker結合。Dokku是一個小型的PaaS平臺,只需使用Git將代碼push到對應的倉庫上就能自動觸發部署,構建過程非常簡單。但是Dokku對于用戶來說,相當于黑盒PaaS,作者想更多的控制部署流程,所以做了一番折騰。不過在我看來,作者的思路卻不是那么容易理解,雖然解決了問題,但卻也違背了初衷,你覺得了?歡迎一起討論。

Docker允許你以統一的方式來部署任何類型的應用。而Dokku是一個基于Docker的小型PaaS平臺。你可以簡單的將代碼倉庫push到服務器上,然后讓Dokku來自動構建并部署應用。

盡管Dokku的自動構建能力非常強大而且很酷,但有時候你想要更多的控制應用的部署。例如,你可能想將應用部署到一個容器里面,然后訪問另一個運行著數據庫的容器。或者你想使用Docker registry上豐富的Docker鏡像。

Dokku有很多社區貢獻的插件,這些插件可以很好的幫助你實現這些需求。但是,你可能仍然會覺得這工具不是很適合你要做事情。畢竟,Docker的最大優勢之一就是它可以讓你在的生產環境和開發環境運行相似或者完全一樣的容器,這也就減少了部署的痛苦。使用Dokku意味著你要放棄了對應用部署的控制。這對于簡單的應用或者測試場景來說可以接受,但是對于比較重要的生產環境來說,你可能就需要奪回這個控制權。

現在我有一些項目需要部署,并且我覺得單臺服務器應該足夠了。我使用預定義好的Docker鏡像在生產環境的服務器上部署這些項目,同時,我又想使用Dokku,因為它支持快速推送代碼到服務器。為此,我們專門研究了如何在單臺服務器上高效的結合Dokku和Docker。

配置服務器

我在DigitalOcean上用預先定義好的Dokku鏡像創建了一個VPS。令人欣喜的是其版本十分的新,Docker和Dokku都是最新的穩定版本。如果你有自己的服務器,你可以像這樣安裝最新的Docker,然后跟著安裝說明安裝Dokku。

使用Dokku來部署一個簡單的應用

在安裝好Dokku后,你需要指定應用部署的域名,并將域名如mydomain.com寫到/home/dokku/VHOST。

現在Dokku運行起來了,我們需要注冊開發機上的SSH key,這樣我們才好將代碼push到Dokku上。在我們的開發機器上運行下面的命令:

cat .ssh/id_rsa.pub| ssh root@mydomain.com sshcommand acl-add dokku myname

(myname可以用來追蹤你的ssh key,方便之后你想刪除)

現在我們可以開始使用Dokku了。要試試是否正常可以檢出(check out)在本地開發環境的一個Node.js的項目,然后將其push到Dokku:

git clone git@github.com:heroku/node-js-sample.git
cd node-js-sample
git remote add dokku dokku@mydomain.com:test
git push dokku master

現在你應該能看到如下輸出:

Counting objects: 381, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (308/308), done.
Writing objects: 100% (381/381), 210.18 KiB | 0 bytes/s, done.
Total 381 (delta 49), reused 373 (delta 44)
-----> Cleaning up ...
-----> Building test ...
-----> Adding BUILD_ENV to build environment...
-----> Node.js app detected
-----> Requested node range: 0.10.x
-----> Resolved node version: 0.10.35
-----> Downloading and installing node
-----> Exporting config vars to environment
-----> Installing dependencies

...

-----> Running post-deploy -----> Creating new /home/dokku/test/VHOST... -----> Configuring test.mydomain.com... -----> Creating http nginx.conf -----> Running nginx-pre-reload    Reloading nginx =====> Application deployed:

http://test.mydomain.com</pre>
正如輸出中說的一樣,你的應用現在部署到了http://test.mydomain.com!

用Docker來部署一個WordPress博客

現在我們已經知道了如何使用Dokku構建應用。現在讓我們來試試部署一個預先定義好的Docker鏡像:我們將要用官方的WordPress Docker鏡像來部署一個博客。但在我們搭建一個新的博客之前,你首先需要搭建好一個MySQL數據庫服務器,我是這么做的:

docker run --name mysql --restart=always \
   -e MYSQL_ROOT_PASSWORD=some-secret-string -d mariadb

命令中的--restart=always選項是用來保證Docker守護進程在容器出錯或者重啟后自動啟動容器。

如果WordPress容器有訪問數據庫服務器的root權限,那它就可以自己設置數據庫,但是我想自己來配置。我并沒有直接在另外一個容器中安裝MySQL客戶端,而是直接在服務器上安裝:

apt-get install -qqy mysql-client
mysql -h`docker inspect --format "{{ .NetworkSettings.IPAddress }}" mysql` \
  -uroot -p

之前的代碼是用來獲取指派給數據庫服務容器的IP地址,以便連接。現在我可以手動為我的新博客搭建好一個數據庫:

CREATE DATABASE myblog;
CREATE USER 'myblog'@'%' IDENTIFIED BY 'another-password';
GRANT ALL ON myblog.* TO 'myblog'@'%';
FLUSH PRIVILEGES;

現在我們可以開始部署WordPress博客了:

docker run --name myblog --link mysql:mysql \
   -e WORDPRESS_DB_USER=myblog -e WORDPRESS_DB_PASSWORD=another-password \
   -e WORDPRESS_DB_NAME=myblog -e VIRTUAL_HOST=blog.mydomain.com \
   --restart=always -d wordpress

現在我們的容器已經開始運行,我們可以用docker ps來確認。然而,我們只能在服務器上直接訪問80端口,VIRTUAL_HOST的環境變量顯示了我們真正想要訪問的地址,但是這還不能用。

用docker-gen來做Nginx的反向代理

在服務器上已經有Nginx運行了,因為Dokku的運行依賴它。現在找到我們博客容器的IP,然后在Nignx中配置好域名和IP的對應關系,這應該不難。問題在于如果博客容器重啟了,例如服務器重啟之后,其IP地址就可能改變,然后我們又需要手動更新Nginx的配置。

幸運的是,有人曾經走過一步,經歷過這樣的折磨,然后弄出了解決方法:docker-gen。這是一個自動構建然后更新所有運行著的容器的配置文件的工具。

讓我們安裝這個神奇的工具吧:

cd /tmp
wget https://github.com/jwilder/docker-gen/releases/download/0.3.6/docker-gen-linux-amd64-0.3.6.tar.gz
tar xzf docker-gen-linux-amd64-0.3.6.tar.gz
mv docker-gen /etc/nginx/docker-gen

現在我們需要為我們想生成的Nginx配置文件創建一個模板。我的配置文件基于jwilder的nginx-proxy,將配置寫到/etc/nginx/docker.template。現在,我們可以運行docker-gen,但是如果我們需要在服務器重啟的時候自動執行此命令,那我們需要將docker-gen安裝成一個service。要做到這一點,我們可以將以下腳本寫到/etc/nginx/docker-gen-service:

#!/bin/bash
/etc/nginx/docker-gen -only-exposed -watch -notify "service nginx reload" \
  /etc/nginx/docker.template /etc/nginx/sites-enabled/docker_containers

然后讓其可執行:chmod +x /etc/nginx/docker-gen-service。現在我們需要添加upstart配置到/etc/init/docker-nginx.conf:

# docker-nginx - Nginx config generator for Docker containers

description "Nginx config generator for Docker containers" author "Somebody <somebody@example.com>"

When to start the service

start on filesystem and started docker

When to stop the service

stop on runlevel [016]

Automatically restart process if crashed

respawn

Send output to logfile

console log

Run before process

pre-start script [ -d /etc/nginx/certs ] || mkdir -p /etc/nginx/certs end script

Start the process

exec /etc/nginx/docker-gen-service</pre>
現在我們可以啟動我們的新服務:initctl start docker-nginx。docker-gen會看著我們所有的Dockder容器,然后更新Nginx文件。它會檢查每一個容器的VIRTUAL_HOST環境變量,還記得我們在的啟動WordPress容器的時候,我們指定了-e VIRTUAL_HOST=blog.mydomain.com選項(如果你想將多個域名指向同一個容器,你可以用逗號分隔:VIRTUAL_HOST=blog.a.com,test.b.com)。因而假設我們的DNS配置是正確的,我們現在可以訪問http://blog.mydomain.com,然后看到熟悉的WordPress的初始化配置界面。

原文鏈接:Dokku and Docker on the same server: power and control(翻譯:鐘最龍 校對:李穎杰)

來自:http://dockerone.com/article/186

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!