嗨,在本教程中,我們将學習如何使用 docker 部署 golang web 應用程式。 你可能已經知道,由于 golang 的高性能和可靠性,docker 是完全是用 golang 寫的。在我們詳細介紹之前,請確定你已經安裝了 docker 以及 golang 并對它們有基本了解。
<a target="_blank"></a>
docker 是一個開源程式,它可以将應用及其完整的依賴包捆綁到一起,并打包為容器,與主控端共享相同的 linux 核心。另一方面,像 vmware 這樣的基于 hypervisor 的虛拟化作業系統容器提供了進階别的隔離和安全性,這是由于客戶機和主機之間的通信是通過 hypervisor 來實作的,它們不共享核心空間。但是硬體仿真也導緻了性能的開銷,是以容器虛拟化誕生了,以提供一個輕量級的虛拟環境,它将一組程序和資源與主機以及其它容器分組及隔離,是以,容器内部的程序無法看到容器外部的程序或資源。
首先我們為 go 應用建立一個目錄,它會在浏覽器中顯示 “hello world”。建立一個 <code>web-app</code> 目錄并使它成為目前目錄。進入 <code>web-app</code> 應用目錄并編輯一個名為 <code>main.go</code> 的檔案。
<code>root@demohost:~# mkdir web-app</code>
<code>root@demohost:~# cd web-app/</code>
<code>root@demohost:~/web-app# vim.tiny main.go</code>
<code></code>
<code>package main</code>
<code>import (</code>
<code>"fmt"</code>
<code>"net/http"</code>
<code>)</code>
<code>func handler(w http.responsewriter, r *http.request) {</code>
<code>fmt.fprintf(w, "hello %s", r.url.path[1:])</code>
<code>}</code>
<code>func main() {</code>
<code>http.handlefunc("/world", handler)</code>
<code>http.listenandserve(":8080", nil)</code>
使用下面的指令運作上面的 “hello world” go 程式。在浏覽器中輸入<code>http://127.0.0.1:8080/world</code> 測試,你會在浏覽器中看到 “hello world”。
<code>root@demohost:~/web-app# port=8080 go run main.go</code>
下一步是将上面的應用在 docker 中容器化。是以我們會建立一個 dockerfile 檔案,它會告訴 docker 如何容器化我們的 web 應用。
<code>root@demohost:~/web-app# vim.tiny dockerfile</code>
<code># 得到最新的 golang docker 鏡像</code>
<code>from golang:latest</code>
<code># 在容器内部建立一個目錄來存儲我們的 web 應用,接着使它成為工作目錄。</code>
<code>run mkdir -p /go/src/web-app</code>
<code>workdir /go/src/web-app</code>
<code># 複制 web-app 目錄到容器中</code>
<code>copy . /go/src/web-app</code>
<code># 下載下傳并安裝第三方依賴到容器中</code>
<code>run go-wrapper download</code>
<code>run go-wrapper install</code>
<code># 設定 port 環境變量</code>
<code>env port 8080</code>
<code># 給主機暴露 8080 端口,這樣外部網絡可以通路你的應用</code>
<code>expose 8080</code>
<code># 告訴 docker 啟動容器運作的指令</code>
<code>cmd ["go-wrapper", "run"]</code>
使用下面的指令建構你的 go web-app,你會在成功建構後獲得确認。
<code>root@demohost:~/web-app# docker build --rm -t web-app .</code>
<code>sending build context to docker daemon 3.584 kb</code>
<code>step 1 : from golang:latest</code>
<code>latest: pulling from library/golang</code>
<code>386a066cd84a: already exists</code>
<code>75ea84187083: pull complete</code>
<code>88b459c9f665: pull complete</code>
<code>a31e17eb9485: pull complete</code>
<code>1b272d7ab8a4: pull complete</code>
<code>eca636a985c1: pull complete</code>
<code>08158782d330: pull complete</code>
<code>digest: sha256:02718aef869a8b00d4a36883c82782b47fc01e774d0ac1afd434934d8ccfee8c</code>
<code>status: downloaded newer image for golang:latest</code>
<code>---> 9752d71739d2</code>
<code>step 2 : run mkdir -p /go/src/web-app</code>
<code>---> running in 9aef92fff9e8</code>
<code>---> 49936ff4f50c</code>
<code>removing intermediate container 9aef92fff9e8</code>
<code>step 3 : workdir /go/src/web-app</code>
<code>---> running in 58440a93534c</code>
<code>---> 0703574296dd</code>
<code>removing intermediate container 58440a93534c</code>
<code>step 4 : copy . /go/src/web-app</code>
<code>---> 82be55bc8e9f</code>
<code>removing intermediate container cae309ac7757</code>
<code>step 5 : run go-wrapper download</code>
<code>---> running in 6168e4e96ab1</code>
<code>+ exec go get -v -d</code>
<code>---> 59664b190fee</code>
<code>removing intermediate container 6168e4e96ab1</code>
<code>step 6 : run go-wrapper install</code>
<code>---> running in e56f093b6f03</code>
<code>+ exec go install -v</code>
<code>web-app</code>
<code>---> 584cd410fdcd</code>
<code>removing intermediate container e56f093b6f03</code>
<code>step 7 : env port 8080</code>
<code>---> running in 298e2a415819</code>
<code>---> c87fd2b43977</code>
<code>removing intermediate container 298e2a415819</code>
<code>step 8 : expose 8080</code>
<code>---> running in 4f639a3790a7</code>
<code>---> 291167229d6f</code>
<code>removing intermediate container 4f639a3790a7</code>
<code>step 9 : cmd go-wrapper run</code>
<code>---> running in 6cb6bc28e406</code>
<code>---> b32ca91bdfe0</code>
<code>removing intermediate container 6cb6bc28e406</code>
<code>successfully built b32ca91bdfe0</code>
現在可以運作我們的 web-app 了,可以執行下面的指令。
<code>root@demohost:~/web-app# docker run -p 8080:8080 --name="test" -d web-app</code>
<code>7644606b9af28a3ef1befd926f216f3058f500ffad44522c1d4756c576cfa85b</code>
進入 <code>http://localhost:8080/world</code> 浏覽你的 web 應用。你已經成功容器化了一個可重複的/确定性的 go web 應用。使用下面的指令來啟動、停止并檢查容器的狀态。
<code>### 列出所有容器</code>
<code>root@demohost:~/ docker ps -a</code>
<code>### 使用 id 啟動容器</code>
<code>root@demohost:~/ docker start container_id_of_web_app</code>
<code>### 使用 id 停止容器</code>
<code>root@demohost:~/ docker stop container_id_of_web_app</code>
要使這個過程自動化,我們将編輯 dockerfile 并安裝 gin 将其作為入口指令來執行。我們将開放 <code>3030</code>端口(gin 代理),而不是 <code>8080</code>。 gin 代理将轉發流量到 web 程式的 <code>8080</code> 端口。
<code># 在容器内部建立一個目錄來存儲我們的 web 應用,接着使它稱為工作目錄。</code>
<code># 複制 web 程式到容器中</code>
<code>run go get github.com/codegangsta/gin</code>
<code>expose 3030</code>
<code># 啟動容器時運作 gin</code>
<code>cmd gin run</code>
現在建構鏡像并啟動容器:
我們會在目前 web 程式的根目錄下運作 docker,并通過暴露的 <code>3030</code> 端口連結 cwd (目前工作目錄)到容器中的應用目錄下。
<code>root@demohost:~/web-app# docker run -p 3030:3030 -v `pwd`:/go/src/web-app --name="test" -d web-app</code>
打開 <code>http://localhost:3030/world</code>, 你就能看到你的 web 程式了。現在如果你改變了任何代碼,會在浏覽器重新整理後反映在你的浏覽器中。
就是這樣,我們的 go web 應用已經運作在 ubuntu 16.04 docker 容器中運作了!你可以通過使用 go 架構來快速開發 api、網絡應用和後端服務,進而擴充目前的網絡應用。
原文釋出時間為:2017-01-12
本文來自雲栖社群合作夥伴“linux中國”