如何在開發和生產環境中使用 Docker 容器化 Golang 應用
Photo by Ian Taylor on Unsplash .
你是否想寫一個使用 Docker 容器化的 Golang 應用程式?本文的目的就是幫助你快速將你的 Golang 應用程式容器化,以用於 開發 (帶熱載入)和 生產 目的。
開始之前
請先安裝 Docker Desktop ,然後再繼續。安裝後,啟動桌面應用程式,如果它執行成功,你就可以開始了。
此外,我假設你有一個 $GOPATH
目錄,你可以在裡面放置你正在處理的 Golang 原始碼。比如我的是: ~/go/src/github.com/bartmika
。
… 但我不熟悉 Docker 怎麼辦?
別擔心!Docker 是一個成熟的工具集,它已經存在了足夠長的時間,可以提供大量優秀的教學資源來幫助你學習。我推薦以下內容,因為它對我幫助很大:
檢視我寫的另外一篇文章,可以幫助你學習基礎知識
-
絕對是面向 Golang 程式設計初學者的 Docker 學習資源
將Golang 和 Docker 用於熱載入的開發環境
在本節中,你將學習如何在你的機器上設定你的 Golang 應用程式進行本地開發。開發容器的目的是儲存所有依賴項(例如:第三方包,如 GORM )、基礎設施(例如:資料庫、記憶體快取等)以及幫助和提升你開發的程式碼。
-
建立我們應用程式的倉庫
mkdir mullberry-backend
cd mullberry-backend
go mod init github.com/bartmika/mullberry-backen
-
每次你想要增加依賴,你都可以關閉當前執行的容器並安裝依賴項。按照如下方式安裝我們的依賴項:
go get github.com/labstack/echo/v4
go get github.com/labstack/echo/v4/[email protected]
-
等等,你需要在本地安裝 Golang 嗎?那麼容器的意義何在?這個 Stackoverflow 使用者在討論為開發目的設定
Dockerfile
時解釋得最好:
當你想要把應用打包到容器中以準備部署時, Dockerfile
是非常棒的。對於希望將原始碼放在容器外部的開發和希望正在執行的容器對原始碼的改變作出反應的開發來說,就不是很合適了。
所以從本質上講,如果你對這個限制沒意見,那就繼續吧!
-
在你的專案的根目錄建立
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("/ping", func(c echo.Context) error {
return c.JSON(http.StatusOK, struct{ Status string }{Status: "OK"})
})
httpPort := os.Getenv("HTTP_PORT")
if httpPort == "" {
httpPort = "8080"
}
e.Logger.Fatal(e.Start(":" + httpPort))
}
注意,上面的程式碼是從 Docker 文件構建你的 Go 映象 複製而來。
-
在建立任何與 docker 相關的內容之前,請建立一個
.dockerignore
檔案 並複製並貼上以下內容:
bin
.dockerignore
Dockerfile
docker-compose.yml
dev.Dockerfile
dev.docker-compose.yml
.env
什麼是 .dockerignore
檔案?本質上,它類似於 .gitignore
其中某些檔案/資料夾不會儲存到 docker 容器和映象中。
-
建立
dev.Dockerfile
檔案並將以下內容複製並貼上到其中。
FROM golang:1.18
# Copy application data into image
COPY . /go/src/bartmika/mullberry-backend
WORKDIR /go/src/bartmika/mullberry-backend
COPY go.mod ./
COPY go.sum ./
RUN go mod download
# Copy only `.go` files, if you want all files to be copied then replace `with `COPY . .` for the code below.
COPY *.go .
# Install our third-party application for hot-reloading capability.
RUN ["go", "get", "github.com/githubnemo/CompileDaemon"]
RUN ["go", "install", "github.com/githubnemo/CompileDaemon"]
ENTRYPOINT CompileDaemon -polling -log-prefix=false -build="go build ." -command="./mullberry-backend" -directory="./"
如果你閱讀上面的註釋,你會注意到 `CompileDaemon` (http://github.com/githubnemo/CompileDaemon) 的用法。那是什麼?本質上它是你的熱載入器!它在一個目錄中監視你的 .go 檔案,如果檔案發生變化,它會呼叫 `go build`。 例如,你在 `Atom` IDE 中開啟這個專案,修改 `main.go` 檔案並點選 _Save_,然後 [`CompileDaemon`](http://github.com/githubnemo/CompileDaemon) 將重建你容器中的 Go 應用程式,所以你可以看到最新的構建!
-
建立我們的 dev.docker-compose.yml 檔案:
version: '3.6'
services:
api:
container_name: mullberry-backend
image: mullberry-backend
ports:
- 8000:8080
volumes:
- ./:/go/src/bartmika/mullberry-backend
build:
dockerfile: dev.Dockerfile
等等,為什麼我對這些 Docker 檔名使用 dev.
字首?原因是因為我想區分用於 生產
和 開發
目的的 Docker 檔案。
-
在你的終端中,使用以下命令啟動開發環境:
$ docker-compose -f dev.docker-compose.yml up
-
確認我們可以訪問它。
$ curl localhost:8000/
-
你將在你的終端中看到以下輸出:
Hello, Docker! <3
如果你看到這個,恭喜你已經準備好開始開發了!如果你想了解更多資訊,請隨時通過他們的 Docker 文件檢視構建你的 Go 映像 一文。
將 Golang 和 Docker 用於生產環境
本節的目的是讓你的 Golang 應用程式容器化並準備好在生產環境中執行。
選項 1:單階段
最簡單的設定就是單階段構建。這樣構建的問題就是你的 Docker 映象將非常大。首先,在你的專案根資料夾中建立一個 Dockerfile
並將以下內容複製並貼上到其中:
FROM golang:1.18
# Copy application data into image
COPY . /go/src/bartmika/mullberry-backend
WORKDIR /go/src/bartmika/mullberry-backend
COPY go.mod ./
COPY go.sum ./
RUN go mod download
# Copy only `.go` files, if you want all files to be copied then replace `with `COPY . .` for the code below.
COPY *.go .
# Build our application.
RUN go build -o ./bin/mullberry-backend
EXPOSE 8080
# Run the application.
CMD ["./bin/mullberry-backend"]
然後執行
up
命令,你將會看到它工作:
$ docker-compose up
選項 2:多階段
一個更復雜的設定被稱為_多階段構建_可以節省磁碟空間。主要思路是你在一個容器中構建你的 Golang 應用程式,然後將它移動到另一個更小的容器中,從而丟棄了磁碟空間沉重的容器。
如果你想嘗試一下,請在專案根資料夾中建立一個 Dockerfile
,然後將以下內容複製並貼上到其中:
##
## Build
##
FROM golang:1.18-alpine as dev-env
# Copy application data into image
COPY . /go/src/bartmika/mullberry-backend
WORKDIR /go/src/bartmika/mullberry-backend
COPY go.mod ./
COPY go.sum ./
RUN go mod download
# Copy only `.go` files, if you want all files to be copied then replace `with `COPY . .` for the code below.
COPY *.go .
# Build our application.
# RUN go build -o /go/src/bartmika/mullberry-backend/bin/mullberry-backend
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags "all=-N -l" -o /server
##
## Deploy
##
FROM alpine:latest
RUN mkdir /data
COPY --from=dev-env /server ./
CMD ["./server"]
然後執行
up
命令,你將會看到它工作:
$ docker-compose up
-------
相關連結:
Ian Taylor : http://unsplash.com/@carrier_lost
Unsplash : http://unsplash.com/photos/jOqJbvo1P9g
Docker Desktop : http://www.docker.com/get-started/
Docker 學習資源:
http://bartlomiejmika.com/post/2021/docker-learning-resources-for-absolute-
beginners-programming-with-golang/
GORM : http://gorm.io/index.html
Stackoverflow:
http://stackoverflow.com/a/71297861
Go 映象 :
http://docs.docker.com/language/golang/build-images/
Go 映像 :
http://docs.docker.com/language/golang/build-images/
-------
原文地址:
http://bartlomiejmika.com/posts/2022/how-to-containerize-a-golang-app-with-docker-for-development-and-production/
原文作者:
Bartlomiej Mika
本文永久連結:
http://github.com/gocn/translator/blob/master/2022/w39_How_to_Containerize_a_Golang_App_With_Docker_for_Development_and_Production.md
譯者 :朱亞光
校對 :劉思家
2022 GopherChina大會報名火熱進行中!
掃描下方二維碼即可報名參與
大會合作、現場招聘及企業購票等事宜請聯絡 微信:18516100522
戳這裡 GO!
- 理解 Go 中的陣列和切片
- 如何在開發和生產環境中使用 Docker 容器化 Golang 應用
- Go元件:context學習筆記!
- 如何用運算子在 Go 中做數學計算
- Go程式語言與環境:萬字長文覆盤導致Go語言成功的那些設計決策
- 從頭開始在 Go 中設計一個無密碼的登入系統
- Go 中簡單的記憶體節省技巧
- 聊一聊跳錶資料結構
- Go Test: 從入門到躺平
- 使用 Go 和 Web 技術構建桌面應用程式
- 構建Go命令列程式工具鏈
- Web 全棧推拉能手 Socket.IO 庫
- ORM 盛行下,你知道真正執行的 sql 麼
- 或許,書應該一起讀
- Go 最細節篇|pprof 統計的記憶體總是偏小?
- go全棧開發框架bud,go語言中的ruby on rails
- 支援300 常用功能的開源GO語言工具函式庫
- Dockertest 極速搭建整合測試環境神器
- 想要輕鬆玩轉Markdown?goldmark幫你實現!
- 「GoCN酷Go推薦」OBS聯結器go-obs-websocket