挺早之前在我寫過一篇用 Docker
搭建LNMP開發環境的文章:用Docker搭建Laravel開發環境,裏面詳細介紹了將 nginx
、 mysql
和 php
三個容器用 docker-compose
編排成 LNMP
開發環境的步驟,今天來講說怎麼用 Docker
快速搭建 Go
語言項目的開發環境。php
由於靠Go
自己自帶的標準庫就能實現高性能的 HTTP
服務器,不熟悉的同窗買它,呃說錯了,看它:深刻學習用Go編寫HTTP服務器。因此用 Docker
構建 Go
的開發環境比構建 LNMP 開發環境要簡單不少,若是沒有太多定製化要求甚至都不用寫 Dockerfile
本身構建鏡像,直接使用官方的 golang
鏡像便可。mysql
咱們使用官方最新穩定版的鏡像 golang:latest
, 獲取鏡像前先得確保你電腦上運行了 Docker
客戶端,沒有的去官網下載一下吧這裏就很少說了。linux
下載dockerHub
上的鏡像直接使用命令:nginx
docker pull golang
複製代碼
下載完鏡像後用鏡像運行一個容器:golang
docker run --rm -it --name go-http-demo golang bash
複製代碼
上面這個命令用鏡像 golang
建立了一個名爲 go-http-demo
的容器,在容器中建立了一個 Bash
會話。--rm
選項指定容器退出後自動移除容器。sql
運行完上面的命令後咱們就進入了運行的容器中,運行 go version
查看如下 go
的版本:docker
root@965425c5bdcf:/go# go version
go version go1.13.6 linux/amd64
root@965425c5bdcf:/go#
複製代碼
你能夠根據本身的須要在https://hub.docker.com/_/golang
中查找本身須要的版本的 golang
鏡像運行容器。shell
咱們使用《深刻學習用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
中,文件目錄大家作的時候根據本身的狀況寫路徑。bash
接下來就要把這個代碼放到容器裏去運行了,切到代碼目錄裏執行以下命令:
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
構建好了一個 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
講的都比較深刻,例子也多,感興趣的能夠看看。
若是本身搭建環境的時候遇到什麼問題了,能夠在這裏留言反饋,也能夠在個人公衆號裏留言反饋。