容器(Container)將程序及其所需的任何內容捆綁在一起,包括依賴項、工具和配置文件等等。這樣使得程序不受環境的干擾,真正意義上做到開發環境和生成環境完全一致。
而 Docker 在容器的基礎上,進行了進一步的封裝,從文件系統、網絡互聯到進程隔離等等,極大的簡化了容器的創建和維護。與傳統虛擬機相比,Docker 也有許多優點,如:更高效的系統資源利用和更快速的啓動時間。
在本文中,通過一個簡單的 Go 語言項目,您將學習如何在 Go 語言項目中使用 Docker。
容器(Container)將程序及其所需的任何內容捆綁在一起,包括依賴項、工具和配置文件等等。這樣使得程序不受環境的干擾,真正意義上做到開發環境和生成環境完全一致。
而 Docker 在容器的基礎上,進行了進一步的封裝,從文件系統、網絡互聯到進程隔離等等,極大的簡化了容器的創建和維護。與傳統虛擬機相比,Docker 也有許多優點,如:更高效的系統資源利用和更快速的啓動時間。
在本文中,通過一個簡單的 Go 語言項目,您將學習如何在 Go 語言項目中使用 Docker。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-IOf4shTt-1591005436769)(https://upload-images.jianshu.io/upload_images/22459064-ca43ab3989bcfc66.png!web?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
創建一個簡單的 Go 語言項目
讓我們來創建一個作爲示例的 Go 語言項目。在命令行下輸入以下命令以創建文件夾:
mkdir gdp
我們將使用 Go Module 進行依賴性管理。轉到項目的根目錄,然後初始化 Go Module:
cd gdp
go mod init github.com/linehk/gdp
我們將創建一個簡單的 hello 服務器。在項目根目錄中創建一個名爲 hello_server.go 的新文件:
touch hello_server.go
文件內容如下:
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/gorilla/mux"
)
func handler(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
name := query.Get("name")
if name == "" {
name = "Guest"
}
log.Printf("Received request for %s.\n", name)
w.Write([]byte(fmt.Sprintf("Hello, %s!\n", name)))
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
server := &http.Server{
Handler: r,
Addr: ":8080",
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
log.Println("Starting Server.")
if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
}
該項目使用 gorilla/mux 包來創建 HTTP 路由(導入包是爲了展示 Docker 容器捆綁依賴項的作用),地址是 localhost:8080 。
嘗試在本地編譯並運行項目
讓我們先嚐試在本地編譯和運行項目。可以在項目根目錄輸入以下命令來編譯項目:
go build
go build 命令將會生成一個名爲 gdp 的可執行文件。可以像這樣運行該文件:
./gdp`
2020/08/19 21:33:49 Starting Server.
我們的 hello 服務器現在正在運行,可以嘗試使用 curl 或其它工具與其交互:
curl http://localhost:8080
Hello, Guest!
curl http://localhost:8080?name=sulinehk
Hello, sulinehk!
編寫 Dockerfile 定義 Docker 鏡像
讓我們來爲這個項目編寫 Dockerfile ,在根目錄創建文件名爲 Dockerfile 的文件,內容如下:
# 拉取 Go 語言最新的基礎鏡像
FROM golang:latest
# 在容器內設置 /app 爲當前工作目錄
WORKDIR /app
# 把文件複製到當前工作目錄
COPY . .
# 設置 GOPROXY 環境變量
ENV GOPROXY="https://goproxy.cn"
# 下載全部依賴項
RUN go mod download
# 編譯項目
RUN go build -o gdp .
# 暴露 8080 端口
EXPOSE 8080
# 執行可執行文件
CMD ["./gdp"]</pre>
構建鏡像和運行容器
鏡像(Image)是實際的軟件分發包,其中包含運行應用程序所需的所有內容。
而容器根據鏡像構建,是鏡像的運行示例,類似 Go 語言中結構體定義和結構體變量之間的關係。
- 構建鏡像:
docker build -t gdp .
- 運行容器:
docker run -d -p 8080:8080 gdp aa6a1afbe1b13ad0b0d1d656e157f762c5fe2229a8e0d95a025df26396ffc08f</pre>
- 與容器內運行的服務器交互:
curl http://localhost:8080
Hello, Guest!</pre>
curl http://localhost:8080?name=sulinehk
Hello, sulinehk!
下面是一些其它的 Docker 命令:
總結
可以看出,一個定義良好的 Dockfile 文件在整個流程中起到承上啓下的作用。