天天看點

如何利用Docker來部署一個go web應用程式

Docker 是一個開源的商業容器産品,友善軟體的統一生産環境和開發環境的安裝部署,它有兩個版本:社群版(Community Edition,縮寫為 CE)和企業版(Enterprise Edition,縮寫為 EE)。企業版包含了一些收費服務,個人開發者一般用不到。本文使用CE版

1.mac docker的安裝

(1)下載下傳mac docker用戶端

https://hub.docker.com/editions/community/docker-ce-desktop-mac

下載下傳安裝後,通過如下指令測試是否安裝成功

➜  ~ docker --version
Docker version 18.09.2, build 6247962
➜  ~ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.
           

docker run hello-world會先從本地找hello-world的image檔案,如果找不到就會到docker hub上pull下來

其他作業系統如Ubuntu的安裝,請參考

https://docs.docker.com/install/linux/docker-ce/ubuntu/

2.image的檢視和删除

image 檔案可以看作是容器的模闆。Docker 把應用程式及其依賴,打包在 image 檔案裡面。隻有通過這個檔案,才能生成 Docker 容器。Docker 根據 image 檔案生成容器的執行個體。同一個 image 檔案,可以生成多個同時運作的容器執行個體。

(1)列出本機的所有image檔案

docker image ls

如何利用Docker來部署一個go web應用程式

(2)删除image檔案

docker image rm [名稱或id]

如何利用Docker來部署一個go web應用程式

如果出現錯誤,無法删除,可以加上 -f 強制删除image

docker rmi -f b99
           

image 檔案是通用的,image 檔案制作完成後,可以上傳到網上的倉庫。Docker 的官方倉庫 Docker Hub 是最重要、最常用的 image 倉庫

3.拉取遠端image檔案

docker image pull [image名稱]
           

4.編寫dockerfile檔案

(1)建立main.go檔案

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	// Set a lower memory limit for multipart forms (default is 32 MiB)
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	r.POST("/upload", func(c *gin.Context) {
		// single file
		file, _ := c.FormFile("file")
		log.Println(file.Filename)

		// Upload the file to specific dst.
		c.SaveUploadedFile(file, "/go/src/app")
		c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
	})
	r.Run(":8080") // listen and serve on 0.0.0.0:8080
}
           

(2)建立Dockerfile檔案

在筆者的工作目錄/Users/hufox/go/src/github.com/puma007/gindocker 下建立Dockerfile檔案

FROM golang:1.11
ENV PATH=$PATH:$GOPATH/bin:$GOROOT/bin
RUN mkdir -p $GOPATH/src/golang.org/x/
WORKDIR $GOPATH/src/golang.org/x
RUN git clone https://github.com/golang/net.git
RUN git clone https://github.com/golang/sys.git
RUN git clone https://github.com/golang/tools.git
RUN git clone https://github.com/golang/text.git
RUN git clone https://github.com/golang/crypto.git
RUN go install ./...
RUN go get -u github.com/gin-gonic/gin
RUN echo $HOME
RUN echo $GOPATH
RUN mkdir /go/src/app
COPY . /go/src/app
WORKDIR /go/src/app
EXPOSE 8080
#RUN go run main.go 這個指令會挂起,導緻無法生成image檔案,應該用cmd
CMD go run main.go
           

(3)生成image檔案

docker image build -t gindocker:1.0 .
           

上面代碼中,

-t

參數用來指定 image 檔案的名字,後面還可以用冒号指定标簽。如果不指定,預設的标簽就是

latest

。最後的那個點表示 Dockerfile 檔案所在的路徑,上例是目前路徑,是以是一個點。

5.運作容器檔案

docker run 指令會從 image 檔案,生成一個正在運作的容器執行個體

例如docker run hello-world

docker container run --rm -p 8080:8080 -it -v /upload:/go/src/app  -w /go/src/app 6c86
           

如果你的映射檔案出錯在macos系統下執行該指令會出錯

docker: Error response from daemon: Mounts denied:

The path /upload

is not shared from OS X and is not known to Docker.

在網上查到如下解釋

Docker for Mac volume mounts behave differently than the base Docker system. This is mostly because Docker tries to comply with Apple's filesystem sandbox guidelines.

如何利用Docker來部署一個go web應用程式

mac系統隻有/Users,/Volumes,/private,/tmp四個目錄以及子目錄可以挂載,打開docker for mac desktop-》perference-》file sharing 隻有列出的目錄及其子目錄可以挂載,将指令修改為

docker container run --rm -p 8080:8080 -it -v /Users/hufox/go/src/github.com/puma007/gindocker:/go/src/app  -w /go/src/app 6c86
           

docker run指令用于從一個image上啟動一個容器

-it 标簽以互動的方式啟動容器;

--rm 标簽在容器終止運作後自動删除容器檔案;

--name gogin-instance 将容器命名為 gogin-instance;

-p 8080:8080 标簽允許通過外部8080端口通路該容器的8080;

-v /Users/hufox/go/src/github.com/puma007/gindocker:/go/src/app 它将主機的/Users/hufox/go/src/github.com/puma007/gindocker映射到容器中的/go/src/app 。這将使得開發檔案在容器的内部和外部都可以通路,并且在容器關閉後檔案要會在主機保留,否則容器關閉後檔案會丢失;

6c86 代表imageid,聲明了用于容器的image;

-w 指定容器的工作目錄為/go/src/app

如果要在容器啟動進入shell指令行,加上 /bin/bash 例如

docker container run -p 8000:3000 -it image名稱:tag /bin/bash
           

6.測試通路

在主控端上我們可以通過

http://localhost:8080/ping
           

通路get請求

在指令下通過:

curl -F "file=@/Users/hufox/data/test.png" localhost:8080/upload
           

發送post請求

參考資料:

[1]https://docs.docker.com/docker-for-mac/

[2]https://docs.docker.com/install/linux/docker-ce/ubuntu/

[3]http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html

[4]https://semaphoreci.com/community/tutorials/how-to-deploy-a-go-web-application-with-docker?spm=a2c4e.11153940.blogcont225570.22.73731da27kbD5S