詳解如何在Docker部署Go程序
開始
首先,我們需要一個簡單的示例項目,以演示如何將Go
項目部署到Docker
容器當中。
運行以下命令創(chuàng)建并初始化一個名稱為GoTest
的項目目錄:
mkdir?GoTest cd?GoTest go?mod?init?GoTest
接著我們編寫一個簡單的web
服務,該服務監(jiān)聽8080
端口:
package?main import?( ?"fmt" ?"net/http" ) func?main()?{ ??fmt.Println("服務啟動......") ??http.HandleFunc("/hello",?func(w?http.ResponseWriter,?r?*http.Request)?{ ??fmt.Fprintln(w,?"hello?world") ?}) ?http.ListenAndServe(":8080",?nil) }
此時我們的示例項目已經創(chuàng)建好了,項目結構如下:
$ tree
.
├── go.mod
├── go.sum
└── main.go
在容器上編譯并運行
創(chuàng)建好了項目之后,要讓項目運行在Docker
容器中,我們需要先創(chuàng)建鏡像,這里用Dockerfile
文件來定制我們的鏡像,Dockerfile
文件代碼如下:
#?基礎鏡像 FROM?golang:alpine #?環(huán)境變量 ENV?GOPROXY?https://goproxy.cn,direct #?創(chuàng)建目錄 RUN?mkdir?/app? #?將源碼復制到app目錄 ADD?.?/app/ #?切換到app目錄 WORKDIR?/app #?編譯源碼 RUN?go?build?-o?main?. #?運行 CMD?["./main"]
在項目直接docker build
命令構建鏡像:
$?docker?build?-t?GoTest:1.0?.
構建成功之后,通過docker images
查看鏡像:
$?docker?image?ls?GoTest:1.0 REPOSITORY???TAG???IMAGE?ID??????CREATED?????????SIZE gotest???????1.0???18e7bd58d94b??20?seconds?ago??309MB
使用該鏡像啟動一個容器:
$?docker?run?-p?8080:8080?GoTest:1.0
使用curl
命令訪問在容器中運行的Web
服務:
$?curl?http://localhost:8080/hello hello?world
先編譯再發(fā)布到容器
我們使用docker images
查看鏡像時,會發(fā)現上述步驟生成的鏡像非常大:
$?docker?image?ls?GoTest:1.0 REPOSITORY?????TAG?????????IMAGE?ID???????CREATED?????????SIZE GoTest?????????1.0?????????18e7bd58d94b???20?seconds?ago??309MB
但如果我們實際編譯項目,會發(fā)現生成的可以執(zhí)行文件是非常小的:
$?ls?-lh?main -rwxr-xr-x??1?sun??staff???5.9M??7??6?16:35?main
可執(zhí)行文件非常小,而構建的鏡像非常大,這是因為我們是以golang:alpine
鏡像為基礎來構建自己的鏡像的,golang:alpine
包含Go
語言的開發(fā)環(huán)境,本身就非常大:
$?docker?image?ls?golang:alpine REPOSITORY?????TAG?????????IMAGE?ID???????CREATED??????????SIZE golang?????????alpine??????722a834ff95b???1?hours?ago??????301MB
如果我們不希望構建好的鏡像太大了,可以先編譯好可執(zhí)行程序,再構建鏡像,此時的Dockerfile
文件簡化如下:
#?以空白鏡像為基礎 FROM?scratch #?將編譯好的可執(zhí)行文件復制到鏡像 ADD?./main?/ #?運行 CMD?["./main"]
編譯可執(zhí)行程序:
$?go?build?-o?main?.
構建鏡像:
$?docker?build?-t?GoTest:2.0
查看鏡像:
$?docker?image?ls?GoTest:2.0 REPOSITORY???????TAG???????????IMAGE?ID?????????CREATED?????????????SIZE gotest???????????2.0???????????8d3b724f8968?????22?seconds?ago??????6.24MB
從上面顯示的結果可以看到,這種方式構建產生的鏡像非常小。
多階鏡像構建
我們在上面使用兩種方式將Go
程序部署到容器中,一種是直接在鏡像中編譯,這種方式構建的鏡像太大了,一種是自己編譯后打包到鏡像,這種方式比較麻煩且不符合一般部署流程。
而使用Docker
的多階鏡像構建可以則將上述兩種方式結合,多階鏡像構建,即在一個Dockerfile
文件可以聲明多個鏡像構建語句,且后面階段的構建可以復制上一階段的文件:
#?第一階構建 FROM?golang:alpine ENV?GOPROXY?https://goproxy.cn,direct RUN?mkdir?/app/ ADD?.?/app/ WORKDIR?/app RUN?CGO_ENABLED=0?GOOS=linux?go?build?-o?main?. #?第二階構建,從空白鏡像開始 FROM?scratch ##?復制上層構建的文件 COPY?--from=0?/app/main?/ CMD?["./main"]
構建鏡像:
$?docker?build?-t?GoTest:3.0
查看鏡像:
$?docker?image?ls?GoTest:3.0 REPOSITORY???????TAG???????????IMAGE?ID?????????CREATED?????????????SIZE gotest???????????3.0???????????8d3b724f8968?????30?seconds?ago??????6.13MB
從上面的結果也可以看出,多階構建產生的鏡像也非常小。
小結
總結一下,直接在鏡像中構建Go項目會使產生的鏡像過大,而手動編譯后再寫入鏡像則略顯繁瑣,多階鏡像構建可以很好地解決這兩個問題。
到此這篇關于詳解如何在Docker部署Go程序的文章就介紹到這了,更多相關Docker部署Go程序內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
docker 部署prometheus+grafana的過程詳解
這篇文章主要介紹了docker 部署prometheus+grafana的過程,本文通過示例圖文相結合給大家介紹的非常詳細,需要的朋友可以參考下2024-03-03使用Docker配置redis sentinel哨兵的方法步驟
本文主要介紹了Docker配置redis sentinel哨兵的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07