亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

如何使用Docker部署Go Web應(yīng)用的實(shí)現(xiàn)

 更新時(shí)間:2020年11月27日 11:07:27   作者:李文周的博客  
這篇文章主要介紹了如何使用Docker部署Go Web應(yīng)用的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

本文介紹了如何使用Docker以及Docker Compose部署我們的 Go Web 程序。

為什么需要Docker?

使用docker的主要目標(biāo)是容器化。也就是為你的應(yīng)用程序提供一致的環(huán)境,而不依賴于它運(yùn)行的主機(jī)。

想象一下你是否也會(huì)遇到下面這個(gè)場(chǎng)景,你在本地開發(fā)了你的應(yīng)用程序,它很可能有很多的依賴環(huán)境或包,甚至對(duì)依賴的具體版本都有嚴(yán)格的要求,當(dāng)開發(fā)過程完成后,你希望將應(yīng)用程序部署到web服務(wù)器。這個(gè)時(shí)候你必須確保所有依賴項(xiàng)都安裝正確并且版本也完全相同,否則應(yīng)用程序可能會(huì)崩潰并無(wú)法運(yùn)行。如果你想在另一個(gè)web服務(wù)器上也部署該應(yīng)用程序,那么你必須從頭開始重復(fù)這個(gè)過程。這種場(chǎng)景就是Docker發(fā)揮作用的地方。

對(duì)于運(yùn)行我們應(yīng)用程序的主機(jī),不管是筆記本電腦還是web服務(wù)器,我們唯一需要做的就是運(yùn)行一個(gè)docker容器平臺(tái)。從以后,你就不需要擔(dān)心你使用的是MacOS,Ubuntu,Arch還是其他。你只需定義一次應(yīng)用,即可隨時(shí)隨地運(yùn)行。

Docker部署示例

準(zhǔn)備代碼

這里我先用一段使用net/http庫(kù)編寫的簡(jiǎn)單代碼為例講解如何使用Docker進(jìn)行部署,后面再講解稍微復(fù)雜一點(diǎn)的項(xiàng)目部署案例。

package main

import (
 "fmt"
 "net/http"
)

func main() {
 http.HandleFunc("/", hello)
 server := &http.Server{
 Addr: ":8888",
 }
 fmt.Println("server startup...")
 if err := server.ListenAndServe(); err != nil {
 fmt.Printf("server startup failed, err:%v\n", err)
 }
}

func hello(w http.ResponseWriter, _ *http.Request) {
 w.Write([]byte("hello liwenzhou.com!"))
}

上面的代碼通過8888端口對(duì)外提供服務(wù),返回一個(gè)字符串響應(yīng):hello liwenzhou.com!。

創(chuàng)建Docker鏡像

鏡像(image)包含運(yùn)行應(yīng)用程序所需的所有東西——代碼或二進(jìn)制文件、運(yùn)行時(shí)、依賴項(xiàng)以及所需的任何其他文件系統(tǒng)對(duì)象。

或者簡(jiǎn)單地說(shuō),鏡像(image)是定義應(yīng)用程序及其運(yùn)行所需的一切。

編寫Dockerfile

要?jiǎng)?chuàng)建Docker鏡像(image)必須在配置文件中指定步驟。這個(gè)文件默認(rèn)我們通常稱之為Dockerfile。(雖然這個(gè)文件名可以隨意命名它,但最好還是使用默認(rèn)的Dockerfile。)

現(xiàn)在我們開始編寫Dockerfile,具體內(nèi)容如下:

注意:某些步驟不是唯一的,可以根據(jù)自己的需要修改諸如文件路徑、最終可執(zhí)行文件的名稱等

FROM golang:alpine

# 為我們的鏡像設(shè)置必要的環(huán)境變量
ENV GO111MODULE=on \
 CGO_ENABLED=0 \
 GOOS=linux \
 GOARCH=amd64

# 移動(dòng)到工作目錄:/build
WORKDIR /build

# 將代碼復(fù)制到容器中
COPY . .

# 將我們的代碼編譯成二進(jìn)制可執(zhí)行文件app
RUN go build -o app .

# 移動(dòng)到用于存放生成的二進(jìn)制文件的 /dist 目錄
WORKDIR /dist

# 將二進(jìn)制文件從 /build 目錄復(fù)制到這里
RUN cp /build/app .

# 聲明服務(wù)端口
EXPOSE 8888

# 啟動(dòng)容器時(shí)運(yùn)行的命令
CMD ["/dist/app"]

Dockerfile解析

From
我們正在使用基礎(chǔ)鏡像golang:alpine來(lái)創(chuàng)建我們的鏡像。這和我們要?jiǎng)?chuàng)建的鏡像一樣是一個(gè)我們能夠訪問的存儲(chǔ)在Docker倉(cāng)庫(kù)的基礎(chǔ)鏡像。這個(gè)鏡像運(yùn)行的是alpine Linux發(fā)行版,該發(fā)行版的大小很小并且內(nèi)置了Go,非常適合我們的用例。有大量公開可用的Docker鏡像,請(qǐng)查看https://hub.docker.com/_/golang

Env
用來(lái)設(shè)置我們編譯階段需要用的環(huán)境變量。

WORKDIR,COPY,RUN
這幾個(gè)命令做的事都寫在注釋里了,很好理解。

EXPORT,CMD
最后,我們聲明服務(wù)端口,因?yàn)槲覀兊膽?yīng)用程序監(jiān)聽的是這個(gè)端口并通過這個(gè)端口對(duì)外提供服務(wù)。并且我們還定義了在我們運(yùn)行鏡像的時(shí)候默認(rèn)執(zhí)行的命令CMD ["/dist/app"]。

構(gòu)建鏡像

在項(xiàng)目目錄下,執(zhí)行下面的命令創(chuàng)建鏡像,并指定鏡像名稱為goweb_app:

docker build . -t goweb_app

等待構(gòu)建過程結(jié)束,輸出如下提示:

...
Successfully built 90d9283286b7
Successfully tagged goweb_app:latest

現(xiàn)在我們已經(jīng)準(zhǔn)備好了鏡像,但是目前它什么也沒做。我們接下來(lái)要做的是運(yùn)行我們的鏡像,以便它能夠處理我們的請(qǐng)求。運(yùn)行中的鏡像稱為容器。

執(zhí)行下面的命令來(lái)運(yùn)行鏡像:

docker run -p 8888:8888 goweb_app

標(biāo)志位-p用來(lái)定義端口綁定。由于容器中的應(yīng)用程序在端口8888上運(yùn)行,我們將其綁定到主機(jī)端口也是8888。如果要綁定到另一個(gè)端口,則可以使用-p $HOST_PORT:8888。例如-p 5000:8888。

現(xiàn)在就可以測(cè)試下我們的web程序是否工作正常,打開瀏覽器輸入http://127.0.0.1:8888就能看到我們事先定義的響應(yīng)內(nèi)容如下:

hello liwenzhou.com!

分階段構(gòu)建示例

我們的Go程序編譯之后會(huì)得到一個(gè)可執(zhí)行的二進(jìn)制文件,其實(shí)在最終的鏡像中是不需要go編譯器的,也就是說(shuō)我們只需要一個(gè)運(yùn)行最終二進(jìn)制文件的容器即可。

Docker的最佳實(shí)踐之一是通過僅保留二進(jìn)制文件來(lái)減小鏡像大小,為此,我們將使用一種稱為多階段構(gòu)建的技術(shù),這意味著我們將通過多個(gè)步驟構(gòu)建鏡像。

FROM golang:alpine AS builder

# 為我們的鏡像設(shè)置必要的環(huán)境變量
ENV GO111MODULE=on \
 CGO_ENABLED=0 \
 GOOS=linux \
 GOARCH=amd64

# 移動(dòng)到工作目錄:/build
WORKDIR /build

# 將代碼復(fù)制到容器中
COPY . .

# 將我們的代碼編譯成二進(jìn)制可執(zhí)行文件 app
RUN go build -o app .

###################
# 接下來(lái)創(chuàng)建一個(gè)小鏡像
###################
FROM scratch

# 從builder鏡像中把/dist/app 拷貝到當(dāng)前目錄
COPY --from=builder /build/app /

# 需要運(yùn)行的命令
ENTRYPOINT ["/app"]

使用這種技術(shù),我們剝離了使用golang:alpine作為編譯鏡像來(lái)編譯得到二進(jìn)制可執(zhí)行文件的過程,并基于scratch生成一個(gè)簡(jiǎn)單的、非常小的新鏡像。我們將二進(jìn)制文件從命名為builder的第一個(gè)鏡像中復(fù)制到新創(chuàng)建的scratch鏡像中。有關(guān)scratch鏡像的更多信息,請(qǐng)查看https://hub.docker.com/_/scratch

附帶其他文件的部署示例

這里以我之前《Go Web視頻教程》中的小清單項(xiàng)目為例,項(xiàng)目的Github倉(cāng)庫(kù)地址為:https://github.com/Q1mi/bubble。

如果項(xiàng)目中帶有靜態(tài)文件或配置文件,需要將其拷貝到最終的鏡像文件中。

我們的bubble項(xiàng)目用到了靜態(tài)文件和配置文件,具體目錄結(jié)構(gòu)如下:

bubble
├── README.md
├── bubble
├── conf
│ └── config.ini
├── controller
│ └── controller.go
├── dao
│ └── mysql.go
├── example.png
├── go.mod
├── go.sum
├── main.go
├── models
│ └── todo.go
├── routers
│ └── routers.go
├── setting
│ └── setting.go
├── static
│ ├── css
│ │ ├── app.8eeeaf31.css
│ │ └── chunk-vendors.57db8905.css
│ ├── fonts
│ │ ├── element-icons.535877f5.woff
│ │ └── element-icons.732389de.ttf
│ └── js
│  ├── app.007f9690.js
│  └── chunk-vendors.ddcb6f91.js
└── templates
 ├── favicon.ico
 └── index.html

我們需要將templates、static、conf三個(gè)文件夾中的內(nèi)容拷貝到最終的鏡像文件中。更新后的Dockerfile如下

FROM golang:alpine AS builder

# 為我們的鏡像設(shè)置必要的環(huán)境變量
ENV GO111MODULE=on \
 CGO_ENABLED=0 \
 GOOS=linux \
 GOARCH=amd64

# 移動(dòng)到工作目錄:/build
WORKDIR /build

# 復(fù)制項(xiàng)目中的 go.mod 和 go.sum文件并下載依賴信息
COPY go.mod .
COPY go.sum .
RUN go mod download

# 將代碼復(fù)制到容器中
COPY . .

# 將我們的代碼編譯成二進(jìn)制可執(zhí)行文件 bubble
RUN go build -o bubble .

###################
# 接下來(lái)創(chuàng)建一個(gè)小鏡像
###################
FROM scratch

COPY ./templates /templates
COPY ./static /static
COPY ./conf /conf

# 從builder鏡像中把/dist/app 拷貝到當(dāng)前目錄
COPY --from=builder /build/bubble /

# 需要運(yùn)行的命令
ENTRYPOINT ["/bubble", "conf/config.ini"]

簡(jiǎn)單來(lái)說(shuō)就是多了幾步COPY的步驟,大家看一下Dockerfile中的注釋即可。

Tips: 這里把COPY靜態(tài)文件的步驟放在上層,把COPY二進(jìn)制可執(zhí)行文件放在下層,爭(zhēng)取多使用緩存。

關(guān)聯(lián)其他容器

又因?yàn)槲覀兊捻?xiàng)目中使用了MySQL,我們可以選擇使用如下命令啟動(dòng)一個(gè)MySQL容器,它的別名為mysql8019;root用戶的密碼為root1234;掛載容器中的/var/lib/mysql到本地的/Users/q1mi/docker/mysql目錄;內(nèi)部服務(wù)端口為3306,映射到外部的13306端口。

docker run --name mysql8019 -p 13306:3306 -e MYSQL_ROOT_PASSWORD=root1234 -v /Users/q1mi/docker/mysql:/var/lib/mysql -d mysql:8.0.19

這里需要修改一下我們程序中配置的MySQL的host地址為容器別名,使它們?cè)趦?nèi)部通過別名(此處為mysql8019)聯(lián)通。

[mysql]
user = root
password = root1234
host = mysql8019
port = 3306
db = bubble

修改后記得重新構(gòu)建bubble_app鏡像:

docker build . -t bubble_app

我們這里運(yùn)行bubble_app容器的時(shí)候需要使用--link的方式與上面的mysql8019容器關(guān)聯(lián)起來(lái),具體命令如下:

docker run --link=mysql8019:mysql8019 -p 8888:8888 bubble_app

Docker Compose模式

除了像上面一樣使用--link的方式來(lái)關(guān)聯(lián)兩個(gè)容器之外,我們還可以使用Docker Compose來(lái)定義和運(yùn)行多個(gè)容器。

Compose是用于定義和運(yùn)行多容器 Docker 應(yīng)用程序的工具。通過 Compose,你可以使用 YML 文件來(lái)配置應(yīng)用程序需要的所有服務(wù)。然后,使用一個(gè)命令,就可以從 YML 文件配置中創(chuàng)建并啟動(dòng)所有服務(wù)。

使用Compose基本上是一個(gè)三步過程:

  1. 使用Dockerfile定義你的應(yīng)用環(huán)境以便可以在任何地方復(fù)制。
  2. 定義組成應(yīng)用程序的服務(wù),docker-compose.yml 以便它們可以在隔離的環(huán)境中一起運(yùn)行。
  3. 執(zhí)行 docker-compose up命令來(lái)啟動(dòng)并運(yùn)行整個(gè)應(yīng)用程序。

我們的項(xiàng)目需要兩個(gè)容器分別運(yùn)行mysql和bubble_app,我們編寫的docker-compose.yml文件內(nèi)容如下:

# yaml 配置
version: "3.7"
services:
 mysql8019:
 image: "mysql:8.0.19"
 ports:
  - "33061:3306"
 command: "--default-authentication-plugin=mysql_native_password --init-file /data/application/init.sql"
 environment:
  MYSQL_ROOT_PASSWORD: "root1234"
  MYSQL_DATABASE: "bubble"
  MYSQL_PASSWORD: "root1234"
 volumes:
  - ./init.sql:/data/application/init.sql
 bubble_app:
 build: .
 command: sh -c "./wait-for.sh mysql8019:3306 -- ./bubble ./conf/config.ini"
 depends_on:
  - mysql8019
 ports:
  - "8888:8888"

這個(gè) Compose 文件定義了兩個(gè)服務(wù):bubble_app 和 mysql8019。其中:

bubble_app
使用當(dāng)前目錄下的Dockerfile文件構(gòu)建鏡像,并通過depends_on指定依賴mysql8019服務(wù),聲明服務(wù)端口8888并綁定對(duì)外8888端口。

mysql8019
mysql8019 服務(wù)使用 Docker Hub 的公共 mysql:8.0.19 鏡像,內(nèi)部端口3306,外部端口33061。

這里需要注意一個(gè)問題就是,我們的bubble_app容器需要等待mysql8019容器正常啟動(dòng)之后再嘗試啟動(dòng),因?yàn)槲覀兊膚eb程序在啟動(dòng)的時(shí)候會(huì)初始化MySQL連接。這里共有兩個(gè)地方要更改,第一個(gè)就是我們Dockerfile中要把最后一句注釋掉:

# Dockerfile
...
# 需要運(yùn)行的命令(注釋掉這一句,因?yàn)樾枰萂ySQL啟動(dòng)之后再啟動(dòng)我們的Web程序)
# ENTRYPOINT ["/bubble", "conf/config.ini"]

第二個(gè)地方是在bubble_app下面添加如下命令,使用提前編寫的wait-for.sh腳本檢測(cè)mysql8019:3306正常后再執(zhí)行后續(xù)啟動(dòng)Web應(yīng)用程序的命令:

command: sh -c "./wait-for.sh mysql8019:3306 -- ./bubble ./conf/config.ini"

當(dāng)然,因?yàn)槲覀儸F(xiàn)在要在bubble_app鏡像中執(zhí)行sh命令,所以不能在使用scratch鏡像構(gòu)建了,這里改為使用debian:stretch-slim,同時(shí)還要安裝wait-for.sh腳本用到的netcat,最后不要忘了把wait-for.sh腳本文件COPY到最終的鏡像中,并賦予可執(zhí)行權(quán)限哦。更新后的Dockerfile內(nèi)容如下:

FROM golang:alpine AS builder

# 為我們的鏡像設(shè)置必要的環(huán)境變量
ENV GO111MODULE=on \
 CGO_ENABLED=0 \
 GOOS=linux \
 GOARCH=amd64

# 移動(dòng)到工作目錄:/build
WORKDIR /build

# 復(fù)制項(xiàng)目中的 go.mod 和 go.sum文件并下載依賴信息
COPY go.mod .
COPY go.sum .
RUN go mod download

# 將代碼復(fù)制到容器中
COPY . .

# 將我們的代碼編譯成二進(jìn)制可執(zhí)行文件 bubble
RUN go build -o bubble .

###################
# 接下來(lái)創(chuàng)建一個(gè)小鏡像
###################
FROM debian:stretch-slim

COPY ./wait-for.sh /
COPY ./templates /templates
COPY ./static /static
COPY ./conf /conf


# 從builder鏡像中把/dist/app 拷貝到當(dāng)前目錄
COPY --from=builder /build/bubble /

RUN set -eux; \
 apt-get update; \
 apt-get install -y \
 --no-install-recommends \
 netcat; \
  chmod 755 wait-for.sh

# 需要運(yùn)行的命令
# ENTRYPOINT ["/bubble", "conf/config.ini"]

所有的條件都準(zhǔn)備就緒后,就可以執(zhí)行下面的命令跑起來(lái)了:

docker-compose up

完整版代碼示例,請(qǐng)查看我的github倉(cāng)庫(kù):https://github.com/Q1mi/deploy_bubble_using_docker。

總結(jié)

使用Docker容器能夠極大簡(jiǎn)化我們?cè)谂渲靡蕾嚟h(huán)境方面的操作,但同時(shí)也對(duì)我們的技術(shù)儲(chǔ)備提了更高的要求。對(duì)于Docker不管你是熟悉抑或是不熟悉,技術(shù)發(fā)展的車輪都滾滾向前。

參考鏈接:

https://levelup.gitconnected.com/complete-guide-to-create-docker-container-for-your-golang-application-80f3fb59a15e

到此這篇關(guān)于如何使用Docker部署Go Web應(yīng)用的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Docker部署Go Web內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Docker中部署nginx服務(wù)的方案

    Docker中部署nginx服務(wù)的方案

    這篇文章主要介紹了Docker中部署nginx服務(wù)的方案的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • docker搭建jenkins服務(wù)的示例

    docker搭建jenkins服務(wù)的示例

    這篇文章主要介紹了docker搭建jenkins服務(wù)的示例,幫助大家更好的理解和使用docker容器,感興趣的朋友可以了解下
    2020-09-09
  • docker容器管理之Docker Engine詳解

    docker容器管理之Docker Engine詳解

    當(dāng)我們運(yùn)行集群Docker引擎時(shí),管理器節(jié)點(diǎn)是管理集群和存儲(chǔ)集群狀態(tài)的關(guān)鍵組件,在這篇文章中我們將了解manager節(jié)點(diǎn)的一些關(guān)鍵功能很重要,以正確部署和維護(hù)集群,需要的朋友可以參考下
    2023-08-08
  • 教你如何獲取Harbor的帶tag的鏡像清單

    教你如何獲取Harbor的帶tag的鏡像清單

    這篇文章主要介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)獲取harbor中全部鏡像的帶tag的清單,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-04-04
  • CentOS7如何修改Docker鏡像默認(rèn)存儲(chǔ)位置

    CentOS7如何修改Docker鏡像默認(rèn)存儲(chǔ)位置

    這篇文章主要介紹了CentOS7如何修改Docker鏡像默認(rèn)存儲(chǔ)位置問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Docker創(chuàng)建tomcat容器實(shí)例后無(wú)法訪問(HTTP狀態(tài)404)

    Docker創(chuàng)建tomcat容器實(shí)例后無(wú)法訪問(HTTP狀態(tài)404)

    本文主要介紹了Docker創(chuàng)建tomcat容器實(shí)例后無(wú)法訪問,HTTP狀態(tài)顯示404,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • Docker部署Mysql8.0.20并配置主從復(fù)制的實(shí)現(xiàn)步驟

    Docker部署Mysql8.0.20并配置主從復(fù)制的實(shí)現(xiàn)步驟

    主從復(fù)制是指數(shù)據(jù)可以從一個(gè)MySQL數(shù)據(jù)庫(kù)服務(wù)器主節(jié)點(diǎn)復(fù)制到一個(gè)或多個(gè)從節(jié)點(diǎn),本文主要介紹了Docker部署Mysql8.0.20并配置主從復(fù)制的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • docker /var/lib/docker/aufs/mnt 目錄清理方法

    docker /var/lib/docker/aufs/mnt 目錄清理方法

    在本篇文章里小編給各位整理的是關(guān)于docker /var/lib/docker/aufs/mnt 目錄清理方法,有需要的朋友們可以參考下。
    2020-03-03
  • docker容器內(nèi)部可以訪問,外部無(wú)法訪問的處理

    docker容器內(nèi)部可以訪問,外部無(wú)法訪問的處理

    這篇文章主要介紹了docker容器內(nèi)部可以訪問,外部無(wú)法訪問的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • docke自定義網(wǎng)絡(luò)之容器互聯(lián)

    docke自定義網(wǎng)絡(luò)之容器互聯(lián)

    大家好,本篇文章主要講的是docke自定義網(wǎng)絡(luò)之容器互聯(lián),感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12

最新評(píng)論