挺早以前在我寫過一篇用 Docker
搭建LNMP開發環境的文章:用Docker搭建Laravel開發環境,裡面詳細介紹了將 nginx
、 mysql
和 php
三個容器用 docker-compose
編排成 LNMP
開發環境的步驟,今天來說說怎麼用 Docker
快速搭建 Go
語言專案的開發環境。
因為靠Go
本身自帶的標準庫就能實現高效能的 HTTP
伺服器,不熟悉的同學買它,呃說錯了,看它:深入學習用Go編寫HTTP伺服器。所以用 Docker
構建 Go
的開發環境比構建 LNMP 開發環境要簡單很多,如果沒有太多定製化要求甚至都不用寫 Dockerfile
自己構建映象,直接使用官方的 golang
映象即可。
獲取Docker映象
我們使用官方最新穩定版的映象 golang:latest
, 獲取映象前先得確保你電腦上執行了 Docker
客戶端,沒有的去官網下載一下吧這裡就不多說了。
下載dockerHub
上的映象直接使用命令:
docker pull golang
下載完映象後用映象執行一個容器:
docker run --rm -it --name go-http-demo golang bash
上面這個命令用映象 golang
建立了一個名為 go-http-demo
的容器,在容器中建立了一個 Bash
會話。--rm
選項指定容器退出後自動移除容器。
執行完上面的命令後我們就進入了執行的容器中,執行 go version
檢視以下 go
的版本:
root@965425c5bdcf:/go# go version
go version go1.13.6 linux/amd64
root@965425c5bdcf:/go#
你可以根據自己的需要在https://hub.docker.com/_/golang
中查詢自己需要的版本的 golang
映象執行容器。
在容器中執行Go專案
我們使用《深入學習用Go編寫HTTP伺服器》中最後寫的支援優雅關停服務的 HTTPServer
的原始碼,將它放到 Docker
容器裡伺服宿主機的請求。HTTP Server
的原始碼如下,想探究程式碼具體怎麼實現的看連結裡的文章就好了。
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
)
func main() {
mux := http.NewServeMux()
mux.Handle("/", &helloHandler{})
server := &http.Server{
Addr: ":8080",
Handler: mux,
}
// 建立系統訊號接收器
done := make(chan os.Signal)
signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-done
if err := server.Shutdown(context.Background()); err != nil {
log.Fatal("Shutdown server:", err)
}
}()
log.Println("Starting HTTP server...")
err := server.ListenAndServe()
if err != nil {
if err == http.ErrServerClosed {
log.Print("Server closed under request")
} else {
log.Fatal("Server closed unexpected")
}
}
}
type helloHandler struct{}
func (*helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}
把原始碼放在本地電腦的 /Code/go/src/example.com/http-demo/main.go
中,檔案目錄你們做的時候根據自己的情況寫路徑。
接下來就要把這個程式碼放到容器裡去執行了,切到程式碼目錄裡執行如下命令:
docker run --rm -it --name go-http-demo \
-v $PWD:/go/src/example.com/go-http-demo \
-p 8000:8080
golang
-v
選項允許我們掛載多個本地目錄或者資料捲到容器中,更改會在容器內外相互同步,上面的命令將 /Code/go/src/example.com/go-http-demo/
掛載到了容器的 /go/src/example.com/go-http-demo
。
-p
指定主機和容器的埠對映,因為程式碼裡 HTTP
服務是監聽 8080
埠的,所以我們將主機的 8000
埠和容器的 8080
埠做了對映。
執行完上面的命令,我們切換到到容器裡的 Bash
會話,切到程式碼目錄執行 go run main.go
後,在自己的電腦上開啟瀏覽器訪問 http:localhost:8080
看到下圖中的頁面就證明伺服器在容器裡已經正常執行起來了。
用 docker-compose 管理容器
通過上面的內容我們已經用 Docker
構建好了一個 Go
的開發環境,不過每次打那堆命令,還要進容器執行 go
命令啟動程式太費事了,我們用 docker-compose
把上面那些流程自動化一下。
在專案程式碼根目錄建立docker-compose.yml
:
version: '3'
services:
app:
image: golang:latest
volumes:
- $PWD:/go/src/examplecom/http_demo
ports:
- "8000:8080"
command: go run /go/src/examplecom/http_demo/main.go
如果你們專案裡不允許就找個目錄放這個檔案,我自己就是單獨有個目錄裡面放了好幾個專案的 Docker
配置檔案,有 PHP
專案的也有 Go
專案的。
上面的編排檔案裡只定義了一個叫 app
的服務,其他的也很容易理解我就不說了,唯一要注意的一點就是如果 yml
檔案在專案外 volumes
裡的配置就換成絕對路徑不要用 $PWD
了
接下來啟動 docker-compose
:
docker-compose up -d
如果啟動不成功先不要在 daemon
模式下執行把 -d
去掉,就能看到具體什麼錯誤,等除錯正常了再後臺啟動。
程式碼有修改後,需要重新編譯專案,針對我們的容器執行下面的命令即可
docker-compose restart
想要進入執行的容器中執行操作使用命令:
docker exec -it <container name> bash
給我們建立的 app
傳送 go test
命令讓它在容器內執行:
docker-compose exec app go test
最近想嘗試把老專案換成用 go mod
管理,專案還是在用 go1.12
所以我就先用 Docker
搭環境,容器隔離的環境怎麼瞎折騰也沒事。今天做的這個開發環境還是很簡單的,沒有用 Dockerfile
自己建立映象, docker-compose
配置檔案裡的設定也很簡單,後面用著不順手有更新了我再推送。下面的兩篇老文章對 Docker
映象和 docker-compose
講的都比較深入,例子也多,感興趣的可以看看。
如果自己搭建環境的時候遇到什麼問題了,可以在這裡留言反饋,也可以在我的公眾號裡留言反饋。
本作品採用《CC 協議》,轉載必須註明作者和本文連結