第1页
資工三 黃瑞安 rueiancsie@gmail.com 2014/09/29
Docker.io
運用 Docker 快速部署
第2页
Docker 是什麼?
Docker 是一個部署工具。它用 Linux 內核的資源 分離機制建立獨立的 Docker Container 來提供 一個抽象層,讓你可以下幾個指令,透過幾個 Container 就將你的服務、應用部署起來。
例如說要部署一個 web app,你可能只需要兩個 Container ,一個跑 psql ,一個跑 nginx,共需要 兩個指令。
第3页
Docker 架構
Docker 是 client-server 的架構。
Docker client 負責與 server 端的 Docker deamon 溝通,下達像是 docker pull、docker run 等指令。一般而言,Docker client 與 Docker deamon 是在同一台機器上面。
第4页
Docker 架構
第5页
Docker 如何使用?
Docker 有三個重要的元件,了解他們對於使用 Docker 會有大的幫助。
● Docker images ● Docker containers ● Docker registries
第6页
Docker Images & Containers
Docker image 是一個用來產生 Container 的樣 板。例如說一個 image 裡面可能會含有一個 ubuntu + Apache + web app,你可以用這個 image 建立出 Container ,並讓它執行 Apache, 這樣就將 web app 部署好了。
Docker 還提供 commit 指令讓你可以基於現有 的 Container 來更新或建立新的 image。
第7页
Docker Registries
Docker Registries 是用來存放 images 的倉庫。 在進行 docker pull 的時候,docker 就會從指定 的 registry 將 image 下載下來。
預設的公用 Registry 就是 Docker Hub,提供如 Github 般的功能。若想自行建立私有 registry 可 以參考 Docker API 文件。
第8页
Docker Hub
Docker Hub 就像如 Github 一般,是個具有社交 功能的公共 image 倉庫。
你可以方便的透過 Docker Hub 下載 image 來使 用或是基於它們來製作你自己的 image,也可以 將你製作好的 image 推上去分享給別人。
第9页
Docker & Docker Hub
1. 與DockerHub詢問 image 在哪裡。 2. DockerHub回覆說在 Registry A。 3. 與Registry A請求該image。 4. Registry A詢問DockerHub該使用者
可否下載此image。 5. DockerHub將回覆 true or false。 6. 若通過驗證,則開始下載 image。
第10页
安裝 Docker
由於 Docker 需要 Linux kernal,在非 Linux 系統 無法使用。Docker 官方提供了 Boot2Docker 這 個基於 VirtualBox 的小工具可以省去安裝虛擬機 的過程。其他如 ubuntu 只需要 apt-get install docker.io 即可安裝。 不過我建議若要在非 Linux 平台上面使用,還是 自己灌一個完整的 Linux 虛擬機,方便使用虛擬 機的資料夾共享功能。
第11页
Docker 常用指令
docker pull docker push docker commit docker diff docker run docker ps docker images docker build ...
下載 image 上傳 image 由 container 製作新的 image 觀看 container 的改變 創建 container 並運行 查看目前的 containers 查看目前的 images 由 Dockerfile 製作新的 image
第12页
用 Docker 部署 Rails App
以 docker 提供的 rails, postgres image 為例 (https://registry.hub.docker.com/_/rails/) (https://registry.hub.docker.com/_/postgres/)
1. 首先運行 postgres 資料庫: $ docker run --name mydb -d postgres
--name 參數是將此 container 命名為 mydb -d 參數是讓此 container 在背景執行
第13页
用 Docker 部署 Rails App
2. 建立你自己的 Rails image:
2.1. 修改你的 config/database.yml 如下
development: adapter: postgresql database: myapp host: <%= ENV[“PG_PORT_5432_TCP_ADDR”] %> username: postgres password: ‘’
2.2. ...
PG_PORT_5432_TCP_ADDR 環境變數將會來自於 mydb container,至於 資料庫的帳號密碼,可從 postgres image 的 Dockerfile 取得。
第14页
用 Docker 部署 Rails App
2. 建立你自己的 Rails image:
2.1. ... 2.2. 在 app 根目錄下面建立 Dockerfile ,內容僅一行:
FROM rails:onbuild 2.3. 接著下指令建立 image:
$ docker build -t myapp-img . -t 參數用來將建立的 image 命名,
第15页
用 Docker 部署 Rails App
3. 開始部署你的 Rails App:
3.1. 第一次先做 migration: $docker run --rm --link mydb:pg myapp-img sh -c “rake db:create & rake db:migrate”
3.2. …
--rm 參數是當這個 container 結束時,就將這個 container 刪除。 --link 參數指定這個 container 要與哪個 container 連接,”:” 後面的是 alias 別名,會將連接進來的環境變數加上別名當作前綴。例如先前更 改 config/database.yml 中的 “PG_PORT_5432_TCP_ADDR”
第16页
用 Docker 部署 Rails App
3. 開始部署你的 Rails image:
3.1. ... 3.2. 接著啟動 rails server:
$docker run --name myapp -d -p 80:3000 --link mydb:pg myapp-img -p 參數這裡是將 container 的 3000 port 對應到 host 的 80 port
第17页
用 Docker 部署 Rails App
4. 部署完成,瀏覽 http://localhost 即可以看見你 的 rails app !
5. 若要將 postgres container 的內容備份出來
$ docker run --rm --volumes-from mydb -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /var/lib/postgresql/data --volumes-from 參數是將 mydb container 的 volume 掛入 -v 參數是在這個 container 創建一個在 /backup 的 volumn,並將 host 的當前目錄 $(pwd) 掛入該 volumn /var/lib/postgresql/data 這個位置可在 postgresql image 的 Dockerfile 找到
第18页
用 Docker 部署 Rails App
6. 用類似的方法還原資料庫
$ docker run --name mydb2 -d postgres $ docker run --rm --volumes-from mydb2 -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar
除了可以還原到同一個 container 之外,我們也可以再創建一個 postgres container (mydb2),再將原本的 container 資料複製進去。 可以利用這技巧去做備份、資料遷移、測試等工作。
第19页
用 Vagrant + Docker 建構 Rails 開發環境
Vagrant 1.6 提供了 Docker 可以作為 Provider 和 Provisioner,用來建構開發環境相當方便,尤其是在 OSX 與 Windows,因為 Vagrant 可以方便解決資料夾 共享還有網路的問題。
第20页
用 Vagrant + Docker 建構 Rails 開發環境
在 Windows 與 OSX 上面使用 docker provider 的話, Vagrant 會自動開一台 VM 來運行 docker,可以完全取 代 boot2docker 工具。
若在 Linux 上使用,Vagrant 則會使用系統內的 docker, 不用透過 host vm。
這樣一來利用 docker,可以讓各個平台都有相同的開發 環境,又比開完整的 VM 省資源。
第21页
用 Vagrant + Docker 建構 Rails 開發環境
在專案根目錄創建 Dockerfile 如下:
FROM phusion/passenger-ruby21:0.9.12
RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
EXPOSE 3000
這次我們使用 phusion/passenger-ruby21 作為 base image,最主要是因 為它有支援 ssh,在開發上會比較方便。ssh 用的 private key 可在此找到 https://github.com/phusion/baseimage-docker#login_ssh
第22页
用 Vagrant + Docker 建構 Rails 開發環境
在 Windows 和 OSX,必須額外為 Vagrant 創建的 docker host vm 設定 port forward 與 synced_folder,才能用來作為開發環境。 專案根目錄下的 Vagrantfile.dockerhost 內容如下:
Vagrant.configure("2") do |config| config.vm.box = "yungsang/boot2docker" config.vm.provision "docker" config.vm.synced_folder ".", "/app" config.vm.network "forwarded_port", guest: 3000, host: 3000
end
第23页
用 Vagrant + Docker 建構 Rails 開發環境
在專案根目錄準備 Vagrantfile 如下:
Vagrant.configure(“2”) do |config| config.vm.define "app" do |v| v.vm.provider "docker" do |d| d.build_dir = "." d.cmd = ["/sbin/my_init", "--enable-insecure-key"] d.ports = ["3000:3000"] d.volumes = ["/app/:/app"] d.has_ssh = true d.vagrant_vagrantfile = "Vagrantfile.dockerhost" end v.ssh.username = "root" v.ssh.private_key_path ="phusion.key" end
end
第24页
用 Vagrant + Docker 建構 Rails 開發環境
Vagrant 的 docker provider 和 provisioner 基本上就是 docker cli 的包 裝。前一頁面這個 Vagrantfile 其實就是先根據當前目錄的 Dockerfile 創 建 image,再透過給定的參數運行起來,與下面指令大致相同:
$ docker run -p 3000:3000 -v /app/:/app image /sbin/my_init --enable-insecure-key
除了這些之外,還有一些其他參數:
d.has_ssh
若為 true,則讓 vagrant ssh 可運作
d.vagrant_vagrantfile 指定 Vagrantfile 來創建 host vm
v.ssh.username
指定 ssh 登入用戶名
v.ssh.private_key_path 指定 ssh 登入用的 private key
第25页
用 Vagrant + Docker 建構 Rails 開發環境
準備好這些 Dockerfile 還有 Vagrantfile 之後,可以執行 $ vagrant up app --provider=docker 來創建 container。
完成後可以用 $ vagrant ssh app 進入該 container 去運行 bundle、rails server 或其他 rake tasks。
其他管理操作指令: $ vagrant global-status $ vagrant status $ vagrant destroy $ vagrant docker-logs $ vagrant docker-run
查看目前所有 vagrant vm(含 host vm) 的情況 查看當前 Vagrantfile 環境的情況 刪除指定 vagrant vm 查看指定 docker container 的 log 運行指定的 docker image
第26页
參考資料
● Docker Tutorial ● About Docker ● Docker User Guide ● Docker CLI Reference ● Dockerfile Reference ● Best Practices for Writing Dockerfiles ● Dockerizing PostgreSQL ● Vagrant: Docker-Based Development Environments ● Vagrant: Docker Configuration ● Phusion Passenger-Docker ● Yungsang Boo2docker Image