構(gòu)建go鏡像實(shí)現(xiàn)過程全面講解
概述
在本教程中,你將生成一個容器映像。該映像包括運(yùn)行應(yīng)用程序所需的一切:編譯的應(yīng)用程序二進(jìn)制文件、運(yùn)行時、庫以及應(yīng)用程序所需的所有其他資源。
前置條件
若要完成本教程,需要滿足以下條件:
- golang 1.19+
- 本地安裝了docker
- Git 客戶端
程序
該應(yīng)用程序提供兩個 HTTP endpoint:
- / 返回符號<3
- /health 返回{ "Status" : "OK"}
應(yīng)用程序偵聽由環(huán)境變量 PORT 定義的 TCP 端口。缺省值為 8080
該應(yīng)用程序的完整源代碼位于 GitHub 上:github.com/docker/docker-gs-ping。我們鼓勵您fork 它并隨心所欲地嘗試它。
要繼續(xù),請將應(yīng)用程序存儲庫克隆到本地計(jì)算機(jī):
git clone https://github.com/docker/docker-gs-ping
如果您熟悉 Go,該應(yīng)用程序 main.go 的文件非常簡單
package main import ( "net/http" "os" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) func main() { e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.GET("/", func(c echo.Context) error { return c.HTML(http.StatusOK, "Hello, Docker! <3") }) e.GET("/health", func(c echo.Context) error { return c.JSON(http.StatusOK, struct{ Status string }{Status: "OK"}) }) httpPort := os.Getenv("PORT") if httpPort == "" { httpPort = "8080" } e.Logger.Fatal(e.Start(":" + httpPort)) } // Simple implementation of an integer minimum // Adapted from: https://gobyexample.com/testing-and-benchmarking func IntMin(a, b int) int { if a < b { return a } return b }
冒煙測試應(yīng)用程序
啟動應(yīng)用程序并確保它正在運(yùn)行。打開終端并導(dǎo)航到將項(xiàng)目存儲庫克隆到的目錄。從現(xiàn)在開始,本指南將此目錄稱為項(xiàng)目目錄
go run main.go
這應(yīng)該將服務(wù)器編譯并啟動為前臺應(yīng)用程序,輸出橫幅,如下圖所示。
____ __ / __/___/ / ___ / _// __/ _ \/ _ \ /___/\__/_//_/\___/ v4.10.2 High performance, minimalist Go web framework https://echo.labstack.com ____________________________________O/_______ O\ a?¨ http server started on [::]:8080
通過訪問 上的 http://localhost:8080 應(yīng)用程序來運(yùn)行快速冒煙測試。您可以使用自己喜歡的 Web 瀏覽器,甚至可以在終端中使用 curl 命令:
curl http://localhost:8080/ Hello, Docker! <3
現(xiàn)在,您可以將其容器化了。
為應(yīng)用程序創(chuàng)建 Dockerfile
告訴 Docker 要為應(yīng)用程序使用哪個基礎(chǔ)映像:
# syntax=docker/dockerfile:1 FROM golang:1.19
Docker 鏡像可以從其他鏡像繼承。因此,您可以使用已經(jīng)具有所有必要工具和庫的官方 Go 映像來編譯和運(yùn)行 Go 應(yīng)用程序,而不是從頭開始創(chuàng)建自己的基礎(chǔ)映像。
現(xiàn)在,您已經(jīng)為即將推出的容器映像定義了基礎(chǔ)映像,可以開始在它之上進(jìn)行構(gòu)建
若要在運(yùn)行其余命令時簡化操作,請?jiān)谝傻挠诚裰袆?chuàng)建一個目錄。這也指示 Docker 使用此目錄作為所有后續(xù)命令的默認(rèn)目標(biāo)。這樣你就不必在 中鍵入完整的文件路徑 Dockerfile ,相對路徑將基于此目錄
WORKDIR /app
通常,一旦你下載了一個用 Go 編寫的項(xiàng)目,你要做的第一件事就是安裝編譯它所需的模塊。請注意,基礎(chǔ)映像已包含工具鏈,但源代碼尚未包含在其中。
因此,在運(yùn)行映像 go mod download 之前,需要將 go.mod 和 go.sum 文件復(fù)制到其中。使用命令 COPY 執(zhí)行此操作。
在最簡單的形式中,該 COPY 命令采用兩個參數(shù)。第一個參數(shù)告訴 Docker 要將哪些文件復(fù)制到映像中。最后一個參數(shù)告訴 Docker 您希望將該文件復(fù)制到何處。
將 go.mod and go.sum 文件復(fù)制到您的項(xiàng)目目錄中,由于您使用了 WORKDIR ,該目錄是映像中的當(dāng)前目錄 /app ( ./ )。與一些現(xiàn)代 shell 似乎對尾部斜杠的使用漠不關(guān)心 ( ),并且可以弄清楚用戶的意思(大多數(shù)時候 / ),Docker COPY 的命令在解釋尾部斜杠時非常敏感。
COPY go.mod go.sum ./
現(xiàn)在,您已經(jīng)在要構(gòu)建的 Docker 映像中擁有模塊文件,也可以使用該命令在該命令中運(yùn)行該 RUN 命令 go mod download 。這與在計(jì)算機(jī)上本地運(yùn)行 go 的工作方式完全相同,但這次這些 Go 模塊將安裝到映像中的目錄中。
RUN go mod download
接下來需要做的是將源代碼復(fù)制到映像中。您將像之前使用模塊文件一樣使用該 COPY 命令。
COPY *.go ./
此 COPY 命令使用通配符將主機(jī)上當(dāng)前目錄(所在的 Dockerfile 目錄)中擴(kuò)展 .go 名的所有文件復(fù)制到映像內(nèi)的當(dāng)前目錄中。
RUN CGO_ENABLED=0 GOOS=linux go build -o /docker-gs-ping
該命令將代碼編譯成一個二進(jìn)制文件,該二進(jìn)制文件被命名 docker-gs-ping 并位于您正在構(gòu)建的映像的文件系統(tǒng)的根目錄中。您可以將二進(jìn)制文件放入該映像中您想要的任何其他位置。
現(xiàn)在,剩下要做的就是告訴 Docker 在使用鏡像啟動容器時要運(yùn)行什么命令。您可以使用以下 CMD 命令執(zhí)行此操作:
CMD ["/docker-gs-ping"]
以下是完整的 Dockerfile :
# syntax=docker/dockerfile:1 FROM golang:1.19 # Set destination for COPY WORKDIR /app # Download Go modules COPY go.mod go.sum ./ RUN go mod download # Copy the source code. Note the slash at the end, as explained in # https://docs.docker.com/engine/reference/builder/#copy COPY *.go ./ # Build RUN CGO_ENABLED=0 GOOS=linux go build -o /docker-gs-ping # Optional: # To bind to a TCP port, runtime parameters must be supplied to the docker command. # But we can document in the Dockerfile what ports # the application is going to listen on by default. # https://docs.docker.com/engine/reference/builder/#expose EXPOSE 8080 # Run CMD ["/docker-gs-ping"]
生成映像
現(xiàn)在,您已經(jīng)創(chuàng)建了 Dockerfile ,讓我們來生成鏡像。 build context 是位于指定路徑或 URL 中的一組文件。Docker 構(gòu)建過程可以訪問context中的任何文件,在這里我們用 . 來標(biāo)識當(dāng)前 context 為同級目錄。
build 命令可以選擇采用標(biāo)志 --tag 。此標(biāo)志用于使用字符串值標(biāo)記圖像,如果不傳遞 , --tag Docker 將用作 latest 默認(rèn)值
構(gòu)建您的第一個 Docker 映像。
docker build --tag docker-gs-ping .
查看本地鏡像
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE docker-gs-ping latest 7f153fbcc0a8 2 minutes ago 1.11GB ...
給鏡像打 tag
鏡像名稱由以斜杠分隔的名稱組件組成。名稱組件可以包含小寫字母、數(shù)字和分隔符。分隔符定義為句點(diǎn)、一個或兩個下劃線或一個或多個破折號。名稱組件不能以分隔符開頭或結(jié)尾。
您可以為圖像設(shè)置多個 tag,事實(shí)上,大多數(shù)圖像都有多個標(biāo)簽。為您構(gòu)建的鏡像打第二個 tag 。使用 docker image tag (或 docker tag 速記)命令為鏡像創(chuàng)建新標(biāo)簽。此命令采用兩個參數(shù);第一個參數(shù)是源圖像,第二個參數(shù)是要創(chuàng)建的新標(biāo)記。以下命令為您構(gòu)建的 docker-gs-ping:latest 創(chuàng)建一個新 docker-gs-ping:v1.0 標(biāo)簽:
docker image tag docker-gs-ping:latest docker-gs-ping:v1.0
現(xiàn)在再次運(yùn)行查看本地鏡像命令,你會看到 tag = v1.0 的鏡像。
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE docker-gs-ping latest 7f153fbcc0a8 6 minutes ago 1.11GB docker-gs-ping v1.0 7f153fbcc0a8 6 minutes ago 1.11GB ...
以上就是構(gòu)建go鏡像實(shí)現(xiàn)過程全面講解的詳細(xì)內(nèi)容,更多關(guān)于構(gòu)建go鏡像的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go項(xiàng)目在linux服務(wù)器的部署詳細(xì)步驟
在今天的軟件開發(fā)中,使用Linux作為操作系統(tǒng)的比例越來越高,而Golang語言則因?yàn)槠涓咝А⒑啙嵑筒l(fā)性能等特點(diǎn),也被越來越多的開發(fā)者所青睞,這篇文章主要給大家介紹了關(guān)于Go項(xiàng)目在linux服務(wù)器的部署詳細(xì)步驟,需要的朋友可以參考下2023-09-09深入理解Golang?make和new的區(qū)別及實(shí)現(xiàn)原理
在Go語言中,有兩個比較雷同的內(nèi)置函數(shù),分別是new和make方法,二者都可以用來分配內(nèi)存,那他們有什么區(qū)別呢?下面我們就從底層來分析一下二者的不同。感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助2022-10-10Go基礎(chǔ)教程系列之?dāng)?shù)據(jù)類型詳細(xì)說明
這篇文章主要介紹了Go基礎(chǔ)教程系列之?dāng)?shù)據(jù)類型詳細(xì)說明,需要的朋友可以參考下2022-04-04