Go 部落格
在 Docker 中部署 Go 伺服器
簡介
本週 Docker 宣布 Go 和其他主要語言的官方基礎映像,讓程式設計人員能以受信任且輕鬆的方式為其 Go 程式建置容器。
在本文中,我們將逐步示範如何為簡易 Go 網路應用程式建立 Docker 容器,並將該容器部署至 Google Compute Engine。如果您不熟悉 Docker,您應該在繼續閱讀前閱讀 了解 Docker。
展示應用程式
在我們的示範中,我們將使用 outyet 程式,該程式來自 Go 實例存放庫,它是一個簡易的網路伺服器,會報告已發布下一版 Go 的資訊(用來支援 isgo1point4.outyet.org 等網站)。它沒有標準函式庫之外的依賴項,且執行時不需要其他資料檔案;對於網路伺服器而言,它已變得非常簡潔。
使用「go get」從您的工作區取得並安裝 outyet
$ go get golang.org/x/example/outyet
編寫 Dockerfile
用以下內容取代 outyet 目錄中名為 Dockerfile 的檔案
# Start from a Debian image with the latest version of Go installed
# and a workspace (GOPATH) configured at /go.
FROM golang
# Copy the local package files to the container's workspace.
ADD . /go/src/golang.org/x/example/outyet
# Build the outyet command inside the container.
# (You may fetch or manage dependencies here,
# either manually or with a tool like "godep".)
RUN go install golang.org/x/example/outyet
# Run the outyet command by default when the container starts.
ENTRYPOINT /go/bin/outyet
# Document that the service listens on port 8080.
EXPOSE 8080
這個 Dockerfile 指定如何建構執行 outyet 的容器,從基本相依性 (安裝 Go 的 Debian 系統;官方 golang docker 影像) 開始,新增 outyet 套件來源,建置它,然後最後執行它。
ADD、RUN 和 ENTRYPOINT 步驟是所有 Go 專案的共同任務。要簡化這項任務,有一個onbuild 衍生自 golang 影像,它會自動複製套件來源、取得應用程式的相依性、建置程式和設定它在啟動時執行。
透過 onbuild 衍生自的檔案,Dockerfile 會簡化許多
FROM golang:onbuild
EXPOSE 8080
建置並執行影像
從 outyet 套件目錄呼叫 Docker 以使用 Dockerfile 建置影像
$ docker build -t outyet .
這樣會從 Docker Hub 取得 golang 基底影像,將套件來源複製到其中,在其中建置套件,並將產生的影像標記為 outyet。
要從產生的影像執行容器
$ docker run --publish 6060:8080 --name test --rm outyet
--publish 旗標告訴 Docker 在外部埠 6060 上公開容器埠 8080。
--name 旗標讓我們容器得到一個可預測名稱,以便更容易操作。
--rm 旗標告訴 Docker 在 outyet 伺服器離開時移除容器影像。
在容器執行時,在網頁瀏覽器中開啟 https://127.0.0.1:6060/ ,您會看到類似這樣的畫面

(如果您的 docker daemon 執行於另一台電腦(或虛擬電腦),您應該將 localhost 取代為該台電腦的位址。如果您使用 OS X 或 Windows 上的 boot2docker,您可以使用 boot2docker ip 找到該位址。)
現在我們已經驗證影像可執行,從另一個終端視窗關閉正在執行的容器
$ docker stop test
在 Docker Hub 上建立儲存庫
Docker Hub,我們先前從中提取 golang 影像的容器登錄,提供一項名為自動建置的功能,它會從 GitHub 或 BitBucket 儲存庫建置影像。
透過提交Dockerfile 到儲存庫並為它建立一個自動建置,任何已安裝 Docker 的人都可以下載並使用單一指令執行我們的影像。(我們會在下一章節看到它的實用性。)
要設定自動建置,將 Dockerfile 提交到您在 GitHub 或 BitBucket 上的存放區,在 Docker Hub 上建立一個帳戶,然後依照指示進行以 建立自動建置。
完成時,可以使用自動建置名稱執行您的容器
$ docker run goexample/outyet
(將 goexample/outyet
取代為您建立的自動建置名稱。
將容器部署至 Google Compute Engine
Google 提供 容器最佳化 Google Compute Engine 映像檔,讓您可以輕鬆建立執行任意 Docker 容器的虛擬機器。在啟動時,執行中的程式會讀取指定要執行哪一個容器的設定檔、取得容器映像檔,然後執行它。
建立一個 containers.yaml 檔案,指定要執行的 Docker 映像檔和外部公開的埠
version: v1beta2
containers:
- name: outyet
image: goexample/outyet
ports:
- name: http
hostPort: 80
containerPort: 8080
(請注意,我們將容器的埠 8080
發布為外部埠 80
,這是提供 HTTP 通信的預設埠。此外,您應該將 goexample/outyet
取代為您的自動建置名稱。)p>
使用 gcloud 工具 建立執行容器的虛擬機器執行個體
$ gcloud compute instances create outyet \
--image container-vm-v20140925 \
--image-project google-containers \
--metadata-from-file google-container-manifest=containers.yaml \
--tags http-server \
--zone us-central1-a \
--machine-type f1-micro
第一個參數 (outyet
) 指定執行個體名稱,只是一個方便的標籤供管理使用。
--image
和 --image-project
旗標指定要使用的特別容器最佳化系統映像檔 (照字面複製這些旗標的內容)。
--metadata-from-file
旗標讓您的虛擬機器可以使用 containers.yaml
檔案。
--tags
旗標將您的虛擬機器執行個體標記為 HTTP 伺服器,調整防火牆讓公眾網路介面公開埠 80。
--zone
和 --machine-type
旗標指定虛擬機器要執行的區域和機器類型。 (要看機器類型和區域的清單,執行 gcloud compute machine-types list
。)p>
在完成之後,gcloud 指令應該會列印一些關於執行個體的資訊。在輸出中,找到 networkInterfaces
部分,找出執行個體的外部 IP 地址。在幾分鐘內,您應該可以使用您的網路瀏覽器存取那個 IP,並且看到「Go 1.4 已發布了嗎?」這個網頁。
(要查看新虛擬機器執行個體的執行狀況,您可以使用 gcloud compute ssh outyet
來透過 SSH 連線其中。在那之後,嘗試 sudo docker ps
以查看哪些 Docker 容器正在執行。)p>
深入了解
這只是冰山一角—有更多您可以使用 Go、Docker 和 Google Compute Engine 執行的動作。
若要深入了解 Docker,請參閱其 完整文件。
若要深入了解 Docker 和 Go,請參閱 官方 golang
Docker Hub 儲存庫 和 Kelsey Hightower 的 針對靜態二進位檔最佳化 Docker 影像。
若要深入了解 Docker 和 Google Compute Engine,請參閱 容器最佳化 VM 網頁 和 google/docker-registry Docker Hub 儲存庫。