摘要:將應(yīng)用部署到項(xiàng)目地址快上車,支持一波原文地址注開始前你需要安裝好,配好鏡像源本章節(jié)源碼在分支上從本章節(jié)開始項(xiàng)目目錄都以為基準(zhǔn)請配合自己本地項(xiàng)目靈活變動介紹在這里簡單介紹下,建議深入學(xué)習(xí)是一個開源的輕量級容器技術(shù),讓開發(fā)者可以打包他們
將Golang應(yīng)用部署到Docker
項(xiàng)目地址:https://github.com/EDDYCJY/go... (快上車,支持一波)
原文地址:https://segmentfault.com/a/11...
注:
開始前你需要安裝好 docker,配好鏡像源
本章節(jié)源碼在 f-20180324-docker 分支上
從本章節(jié)開始 項(xiàng)目目錄都以 go-gin-example 為基準(zhǔn)(請配合自己本地項(xiàng)目靈活變動)
介紹在這里簡單介紹下Docker,建議深入學(xué)習(xí)
Docker 是一個開源的輕量級容器技術(shù),讓開發(fā)者可以打包他們的應(yīng)用以及應(yīng)用運(yùn)行的上下文環(huán)境到一個可移植的鏡像中,然后發(fā)布到任何支持Docker的系統(tǒng)上運(yùn)行。 通過容器技術(shù),在幾乎沒有性能開銷的情況下,Docker 為應(yīng)用提供了一個隔離運(yùn)行環(huán)境
簡化配置
代碼流水線管理
提高開發(fā)效率
隔離應(yīng)用
快速、持續(xù)部署
接下來我們正式開始對項(xiàng)目進(jìn)行 docker 的所需處理和編寫,每一個大標(biāo)題為步驟大綱
Golang 一、編寫Dockerfile在 go-gin-example 項(xiàng)目根目錄創(chuàng)建 Dockerfile 文件,寫入內(nèi)容
FROM golang:latest WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example RUN go build . EXPOSE 8000 ENTRYPOINT ["./go-gin-example"]作用
golang:latest 鏡像為基礎(chǔ)鏡像,將工作目錄設(shè)置為 $GOPATH/src/go-gin-example,并將當(dāng)前上下文目錄的內(nèi)容復(fù)制到 $GOPATH/src/go-gin-example 中
在進(jìn)行 go build 編譯完畢后,將容器啟動程序設(shè)置為 ./go-gin-example,也就是我們所編譯的可執(zhí)行文件
注意 go-gin-example 在 docker 容器里編譯,并沒有在宿主機(jī)現(xiàn)場編譯
說明Dockerfile 文件是用于定義 Docker 鏡像生成流程的配置文件,文件內(nèi)容是一條條指令,每一條指令構(gòu)建一層,因此每一條指令的內(nèi)容,就是描述該層應(yīng)當(dāng)如何構(gòu)建;這些指令應(yīng)用于基礎(chǔ)鏡像并最終創(chuàng)建一個新的鏡像
你可以認(rèn)為用于快速創(chuàng)建自定義的 Docker 鏡像
1、 FROM
指定基礎(chǔ)鏡像(必須有的指令,并且必須是第一條指令)
2、 WORKDIR
格式為 WORKDIR <工作目錄路徑>
使用 WORKDIR 指令可以來指定工作目錄(或者稱為當(dāng)前目錄),以后各層的當(dāng)前目錄就被改為指定的目錄,如果目錄不存在,WORKDIR 會幫你建立目錄
3、COPY
格式:
COPY <源路徑>... <目標(biāo)路徑> COPY ["<源路徑1>",... "<目標(biāo)路徑>"]
COPY 指令將從構(gòu)建上下文目錄中 <源路徑> 的文件/目錄復(fù)制到新的一層的鏡像內(nèi)的 <目標(biāo)路徑> 位置
4、RUN
用于執(zhí)行命令行命令
格式:RUN <命令>
5、EXPOSE
格式為 EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是聲明運(yùn)行時容器提供服務(wù)端口,這只是一個聲明,在運(yùn)行時并不會因?yàn)檫@個聲明應(yīng)用就會開啟這個端口的服務(wù)
在 Dockerfile 中寫入這樣的聲明有兩個好處
幫助鏡像使用者理解這個鏡像服務(wù)的守護(hù)端口,以方便配置映射
運(yùn)行時使用隨機(jī)端口映射時,也就是 docker run -P 時,會自動隨機(jī)映射 EXPOSE 的端口
6、ENTRYPOINT
ENTRYPOINT 的格式和 RUN 指令格式一樣,分為兩種格式
exec 格式:
" "
shell 格式:
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
ENTRYPOINT 指令是指定容器啟動程序及參數(shù)
二、構(gòu)建鏡像go-gin-example 的項(xiàng)目根目錄下執(zhí)行 docker build -t gin-blog-docker .
該命令作用是創(chuàng)建/構(gòu)建鏡像,-t 指定名稱為 gin-blog-docker,. 構(gòu)建內(nèi)容為當(dāng)前上下文目錄
$ docker build -t gin-blog-docker . Sending build context to Docker daemon 96.39 MB Step 1/6 : FROM golang:latest ---> d632bbfe5767 Step 2/6 : WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 56294f978c5d Removing intermediate container e112997b995d Step 3/6 : COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 3b60960120cf Removing intermediate container 63e310b3f60c Step 4/6 : RUN go build . ---> Running in 52648a431450 ---> 7bfbeb301fea Removing intermediate container 52648a431450 Step 5/6 : EXPOSE 8000 ---> Running in 98f5b387d1bb ---> b65bd4076c65 Removing intermediate container 98f5b387d1bb Step 6/6 : ENTRYPOINT ./go-gin-example ---> Running in c4f6cdeb667b ---> d8a109c7697c Removing intermediate container c4f6cdeb667b Successfully built d8a109c7697c三、驗(yàn)證鏡像
查看所有的鏡像,確定剛剛構(gòu)建的 gin-blog-docker 鏡像是否存在
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE gin-blog-docker latest d8a109c7697c About a minute ago 946 MB docker.io/golang latest d632bbfe5767 8 days ago 779 MB ...四、創(chuàng)建并運(yùn)行一個新容器
執(zhí)行命令 docker run -p 8000:8000 gin-blog-docker
$ docker run -p 8000:8000 gin-blog-docker dial tcp 127.0.0.1:3306: connect: connection refused [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) ... Actual pid is 1
運(yùn)行成功,你以為大功告成了嗎?
你想太多了,仔細(xì)看看控制臺的輸出了一條錯誤 dial tcp 127.0.0.1:3306: connect: connection refused
我們研判一下,發(fā)現(xiàn)是 Mysql 的問題,接下來第二項(xiàng)我們將解決這個問題
Mysql 一、拉取鏡像從 Docker 的公共倉庫 Dockerhub 下載 MySQL 鏡像(國內(nèi)建議配個鏡像)
$ docker pull mysql二、創(chuàng)建并運(yùn)行一個新容器
運(yùn)行 Mysql 容器,并設(shè)置執(zhí)行成功后返回容器ID
$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootroot -d mysql 8c86ac986da4922492934b6fe074254c9165b8ee3e184d29865921b0fef29e64連接 Mysql
初始化的 Mysql 應(yīng)該如圖
Golang + Mysql 一、刪除鏡像由于原本的鏡像存在問題,我們需要刪除它,此處有幾種做法
刪除原本有問題的鏡像,重新構(gòu)建一個新鏡像
重新構(gòu)建一個不同 name、tag 的新鏡像
刪除原本的有問題的鏡像,-f 是強(qiáng)制刪除及其關(guān)聯(lián)狀態(tài)
若不執(zhí)行 -f,你需要執(zhí)行 docker ps -a 查到所關(guān)聯(lián)的容器,將其 rm 解除兩者依賴關(guān)系
$ docker rmi -f gin-blog-docker Untagged: gin-blog-docker:latest Deleted: sha256:d8a109c7697c3c2d9b4de7dbb49669d10106902122817b6467a031706bc52ab4 Deleted: sha256:b65bd4076c65a3c24029ca4def3b3f37001ff7c9eca09e2590c4d29e1e23dce5 Deleted: sha256:7bfbeb301fea9d8912a4b7c43e4bb8b69bdc57f0b416b372bfb6510e476a7dee Deleted: sha256:3b60960120cf619181c1762cdc1b8ce318b8c815e056659809252dd321bcb642 Deleted: sha256:56294f978c5dfcfa4afa8ad033fd76b755b7ecb5237c6829550741a4d2ce10bc二、修改配置文件
將項(xiàng)目的配置文件 conf/app.ini,內(nèi)容修改為
#debug or release RUN_MODE = debug [app] PAGE_SIZE = 10 JWT_SECRET = 233 [server] HTTP_PORT = 8000 READ_TIMEOUT = 60 WRITE_TIMEOUT = 60 [database] TYPE = mysql USER = root PASSWORD = rootroot HOST = mysql:3306 NAME = blog TABLE_PREFIX = blog_三、重新構(gòu)建鏡像
重復(fù)先前的步驟,回到 gin-blog 的項(xiàng)目根目錄下執(zhí)行 docker build -t gin-blog-docker .
四、創(chuàng)建并運(yùn)行一個新容器 關(guān)聯(lián)Q:我們需要將 Golang 容器和 Mysql 容器關(guān)聯(lián)起來,那么我們需要怎么做呢?
A:增加命令 --link mysql:mysql 讓 Golang 容器與 Mysql 容器互聯(lián);通過 --link,可以在容器內(nèi)直接使用其關(guān)聯(lián)的容器別名進(jìn)行訪問,而不通過IP,但是--link只能解決單機(jī)容器間的關(guān)聯(lián),在分布式多機(jī)的情況下,需要通過別的方式進(jìn)行連接
運(yùn)行執(zhí)行命令 docker run --link mysql:mysql -p 8000:8000 gin-blog-docker
$ docker run --link mysql:mysql -p 8000:8000 gin-blog-docker [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) ... Actual pid is 1結(jié)果
檢查啟動輸出、接口測試、數(shù)據(jù)庫內(nèi)數(shù)據(jù),均正常;我們的 Golang 容器和 Mysql 容器成功關(guān)聯(lián)運(yùn)行,大功告成 :)
雖然應(yīng)用已經(jīng)能夠跑起來了
但如果對 Golang 和 Docker 有一定的了解,我希望你能夠想到至少2個問題
為什么 gin-blog-docker 占用空間這么大?(可用 docker ps -as | grep gin-blog-docker 查看)
Mysql 容器直接這么使用,數(shù)據(jù)存儲到哪里去了?
創(chuàng)建超小的Golang鏡像Q:第一個問題,為什么這么鏡像體積這么大?
A:FROM golang:latest 拉取的是官方 golang 鏡像,包含Golang的編譯和運(yùn)行環(huán)境,外加一堆GCC、build工具,相當(dāng)齊全
這是有問題的,我們可以不在Golang容器中現(xiàn)場編譯的,壓根用不到那些東西,我們只需要一個能夠運(yùn)行可執(zhí)行文件的環(huán)境即可
構(gòu)建Scratch鏡像Scratch鏡像,簡潔、小巧,基本是個空鏡像
FROM scratch WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example EXPOSE 8000 CMD ["./go-gin-example"]
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o go-gin-example .
編譯所生成的可執(zhí)行文件會依賴一些庫,并且是動態(tài)鏈接。在這里因?yàn)槭褂玫氖?scratch 鏡像,它是空鏡像,因此我們需要將生成的可執(zhí)行文件靜態(tài)鏈接所依賴的庫
$ docker build -t gin-blog-docker-scratch . Sending build context to Docker daemon 133.1 MB Step 1/5 : FROM scratch ---> Step 2/5 : WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> Using cache ---> ee07e166a638 Step 3/5 : COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 1489a0693d51 Removing intermediate container e3e9efc0fe4d Step 4/5 : EXPOSE 8000 ---> Running in b5630de5544a ---> 6993e9f8c944 Removing intermediate container b5630de5544a Step 5/5 : CMD ./go-gin-example ---> Running in eebc0d8628ae ---> 5310bebeb86a Removing intermediate container eebc0d8628ae Successfully built 5310bebeb86a
注意,假設(shè)你的Golang應(yīng)用沒有依賴任何的配置等文件,是可以直接把可執(zhí)行文件給拷貝進(jìn)去即可,其他都不必關(guān)心
這里可以有好幾種解決方案
依賴文件統(tǒng)一管理掛載
go-bindata 一下
...
因此這里如果解決了文件依賴的問題后,就不需要把目錄給 COPY 進(jìn)去了
$ docker run --link mysql:mysql -p 8000:8000 gin-blog-docker-scratch [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /auth --> github.com/EDDYCJY/go-gin-example/routers/api.GetAuth (3 handlers) ...
成功運(yùn)行,程序也正常接收請求
接下來我們再看看占用大小,執(zhí)行 docker ps -as 命令
$ docker ps -as CONTAINER ID IMAGE COMMAND ... SIZE 9ebdba5a8445 gin-blog-docker-scratch "./go-gin-example" ... 0 B (virtual 132 MB) 427ee79e6857 gin-blog-docker "./go-gin-example" ... 0 B (virtual 946 MB)
從結(jié)果而言,占用大小以Scratch鏡像為基礎(chǔ)的容器完勝,完成目標(biāo)
Mysql掛載數(shù)據(jù)卷倘若不做任何干涉,在每次啟動一個 Mysql 容器時,數(shù)據(jù)庫都是空的。另外容器刪除之后,數(shù)據(jù)就丟失了(還有各類意外情況),非常糟糕!
數(shù)據(jù)卷數(shù)據(jù)卷 是被設(shè)計(jì)用來持久化數(shù)據(jù)的,它的生命周期獨(dú)立于容器,Docker 不會在容器被刪除后自動刪除 數(shù)據(jù)卷,并且也不存在垃圾回收這樣的機(jī)制來處理沒有任何容器引用的 數(shù)據(jù)卷。如果需要在刪除容器的同時移除數(shù)據(jù)卷??梢栽趧h除容器的時候使用 docker rm -v 這個命令
數(shù)據(jù)卷 是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:
數(shù)據(jù)卷 可以在容器之間共享和重用
對 數(shù)據(jù)卷 的修改會立馬生效
對 數(shù)據(jù)卷 的更新,不會影響鏡像
數(shù)據(jù)卷 默認(rèn)會一直存在,即使容器被刪除
注意:數(shù)據(jù)卷 的使用,類似于 Linux 下對目錄或文件進(jìn)行 mount,鏡像中的被指定為掛載點(diǎn)的目錄中的文件會隱藏掉,能顯示看的是掛載的 數(shù)據(jù)卷。如何掛載
首先創(chuàng)建一個目錄用于存放數(shù)據(jù)卷;示例目錄 /data/docker-mysql,注意 --name 原本名稱為 mysql 的容器,需要將其刪除 docker rm
$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootroot -v /data/docker-mysql:/var/lib/mysql -d mysql 54611dbcd62eca33fb320f3f624c7941f15697d998f40b24ee535a1acf93ae72
創(chuàng)建成功,檢查目錄 /data/docker-mysql,下面多了不少數(shù)據(jù)庫文件
驗(yàn)證接下來交由你進(jìn)行驗(yàn)證,目標(biāo)是創(chuàng)建一些測試表和數(shù)據(jù),然后刪除當(dāng)前容器,重新創(chuàng)建的容器,數(shù)據(jù)庫數(shù)據(jù)也依然存在(當(dāng)然了數(shù)據(jù)卷指向要一致)
我已驗(yàn)證完畢,你呢?
參考 本系列示例代碼go-gin-example
本系列目錄連載一 Golang介紹與環(huán)境安裝
連載二 搭建Blog API"s(一)
連載三 搭建Blog API"s(二)
連載四 搭建Blog API"s(三)
連載五 使用JWT進(jìn)行身份校驗(yàn)
連載六 編寫一個簡單的文件日志
連載七 Golang優(yōu)雅重啟HTTP服務(wù)
連載八 為它加上Swagger
連載九 將Golang應(yīng)用部署到Docker
連載十 定制 GORM Callbacks
連載十一 Cron定時任務(wù)
連載十二 優(yōu)化配置結(jié)構(gòu)及實(shí)現(xiàn)圖片上傳
連載十三 優(yōu)化你的應(yīng)用結(jié)構(gòu)和實(shí)現(xiàn)Redis緩存
連載十四 實(shí)現(xiàn)導(dǎo)出、導(dǎo)入 Excel
連載十五 生成二維碼、合并海報(bào)
連載十六 在圖片上繪制文字
連載十七 用 Nginx 部署 Go 應(yīng)用
番外 Golang交叉編譯
番外 請入門 Makefile
書籍Docker —— 從入門到實(shí)踐
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/27228.html
摘要:將應(yīng)用部署到項(xiàng)目地址快上車,支持一波原文地址注開始前你需要安裝好,配好鏡像源本章節(jié)源碼在分支上從本章節(jié)開始項(xiàng)目目錄都以為基準(zhǔn)請配合自己本地項(xiàng)目靈活變動介紹在這里簡單介紹下,建議深入學(xué)習(xí)是一個開源的輕量級容器技術(shù),讓開發(fā)者可以打包他們 將Golang應(yīng)用部署到Docker 項(xiàng)目地址:https://github.com/EDDYCJY/go... (快上車,支持一波)原文地址:https...
摘要:交叉編譯項(xiàng)目地址快上車,支持一波原文地址前言在連載九講解構(gòu)建鏡像時,我們編譯可執(zhí)行文件用了另外一個形式的命令,不知道你有沒有疑問說明我們將講解命令各個參數(shù)的作用,希望你在閱讀時,將每一項(xiàng)串聯(lián)起來,你會發(fā)現(xiàn)這就是交叉編譯相關(guān)的小知識 Golang交叉編譯 項(xiàng)目地址:https://github.com/EDDYCJY/go... (快上車,支持一波) 原文地址:https://segme...
摘要:交叉編譯項(xiàng)目地址快上車,支持一波原文地址前言在連載九講解構(gòu)建鏡像時,我們編譯可執(zhí)行文件用了另外一個形式的命令,不知道你有沒有疑問說明我們將講解命令各個參數(shù)的作用,希望你在閱讀時,將每一項(xiàng)串聯(lián)起來,你會發(fā)現(xiàn)這就是交叉編譯相關(guān)的小知識 Golang交叉編譯 項(xiàng)目地址:https://github.com/EDDYCJY/go... (快上車,支持一波) 原文地址:https://segme...
閱讀 1548·2021-11-04 16:10
閱讀 2806·2021-09-30 09:48
閱讀 2849·2019-08-29 11:31
閱讀 1586·2019-08-28 18:22
閱讀 3239·2019-08-26 13:44
閱讀 1329·2019-08-26 13:42
閱讀 2854·2019-08-26 10:20
閱讀 764·2019-08-23 17:00