如何使用Docker部署Go Web应用的实现

如何使用Docker部署Go Web应用的实现,第1张

如何使用Docker部署GoWeb应用的实现

本文主要介绍如何使用Docker部署GoWeb应用的实现。通过示例代码进行了非常详细的介绍,对于大家的学习或者工作都有一定的参考价值。有需要的朋友下面和边肖一起学习。

本文介绍了如何使用Docker和DockerCompose来部署我们的GoWeb程序。

为什么需要Docker?

使用docker的主要目的是容器化。那就是为您的应用程序提供一个一致的环境,不管它运行在哪个主机上。

想象一下你是否也会遇到下面的场景。您已经在本地开发了您的应用程序。它大概有很多依赖的环境或者包,甚至对依赖的具体版本有严格的要求。开发过程完成后,您希望将应用程序部署到web服务器上。此时,您必须确保所有依赖项安装正确并且版本相同,否则应用程序可能会崩溃并且无法运行。如果您想在另一个web服务器上部署应用程序,您必须从头开始重复这个过程。这种场景就是Docker发挥作用的地方。

对于运行我们的应用程序的主机,无论是笔记本电脑还是web服务器,我们唯一需要做的就是运行docker容器平台。从现在开始,你就不需要担心你用的是MacOS,Ubuntu,Arch还是别的什么了。应用只需要定义一次,随时随地都可以运行。

Docker部署示例
准备代码

这里我将以一个用net/http库编写的简单代码为例,说明如何使用Docker进行部署,然后再说明一个稍微复杂一点的项目部署案例。

packagemain import( "fmt" "net/http" ) funcmain(){ http.HandleFunc("/",hello) server:=&http.Server{ Addr:":8888", } fmt.Println("serverstartup...") iferr:=server.ListenAndServe();err!=nil{ fmt.Printf("serverstartupfailed,err:%v\n",err) } } funchello(whttp.ResponseWriter,_*http.Request){ w.Write([]byte("helloliwenzhou.com!")) }

上面的代码通过端口8888提供外部服务,并返回一个字符串响应:你好,liwenzhou.com!。

创建Docker镜像

Image包含运行应用程序所需的一切——代码或二进制文件、运行时、依赖项以及所需的任何其他文件系统对象。

或者简单地说,图像是定义应用程序及其 *** 作所需的一切。

编写Dockerfile

要创建Docker映像,必须在配置文件中指定步骤。默认情况下,这个文件称为Dockerfile。(虽然这个文件名可以任意命名,但是最好使用默认的Dockerfile。)

现在让我们开始编写Dockerfile,如下所示:

注意:有些步骤不是唯一的。您可以修改文件路径、最终可执行文件的名称等。根据自己的需求。

FROMgolang:alpine #为我们的镜像设置必要的环境变量 ENVGO111MODULE=on\ CGO_ENABLED=0\ GOOS=linux\ GOARCH=amd64 #移动到工作目录:/build WORKDIR/build #将代码复制到容器中 COPY.. #将我们的代码编译成二进制可执行文件app RUNgobuild-oapp. #移动到用于存放生成的二进制文件的/dist目录 WORKDIR/dist #将二进制文件从/build目录复制到这里 RUNcp/build/app. #声明服务端口 EXPOSE8888 #启动容器时运行的命令 CMD["/dist/app"]

Dockerfile解析

From
我们正在使用基础镜像golang:alpine来创建我们的镜像。就像我们想要创建的图像一样,这是一个存储在Dockerwarehouse中的基本图像,我们可以访问它。这张图运行的是alpineLinux发行版,非常小,内置了Go,非常适合我们的用例。有大量公开的码头工人图像,请检查https://hub.docker.com/_/golang.

Env
用于设置我们在编译阶段需要的环境变量。

WORKDIR,COPY,RUN
这些命令做什么都写在评论里了,很好理解。

EXPORT,CMD
最后我们声明服务端口,因为我们的应用程序监听这个端口,通过这个端口向外界提供服务。我们还定义了命令CMD["/dist/app"],在运行映像时,默认情况下会执行该命令。

构建镜像

在项目目录中,执行以下命令创建镜像,并将镜像的名称指定为goweb_app:

dockerbuild.-tgoweb_app

等待构建过程结束,并输出以下提示:

...
成功构建90d9283286b7
成功标记goweb_app:latest

现在我们准备了镜像,但目前它什么也没做。我们接下来要做的是运行我们的镜像,以便它可以处理我们的请求。中运行的镜像称为容器。

执行以下命令来运行镜像:

dockerrun-p8888:8888goweb_app

Bit-p用于定义端口绑定。因为容器中的应用程序运行在端口8888上,所以我们将它绑定到主机端口,该端口也是8888。如果想绑定到另一个端口,可以使用-p$HOST_PORT:8888。例如-p5000:8888。

现在您可以测试我们的web程序是否正常工作。打开浏览器并键入http://127.0.0.1:8888,您将看到我们预定义的响应内容如下:

helloliwenzhou.com! 分阶段构建示例

我们的go程序编译完成后,会得到一个可执行的二进制文件。事实上,我们在最终映像中不需要Go编译器,这意味着我们只需要一个容器来运行最终的二进制文件。

Docker的最佳实践之一是通过只保留二进制文件来减小图像大小。为此,我们将使用一种称为多阶段构建的技术,这意味着我们将分多个步骤构建映像。

FROMgolang:alpineASbuilder #为我们的镜像设置必要的环境变量 ENVGO111MODULE=on\ CGO_ENABLED=0\ GOOS=linux\ GOARCH=amd64 #移动到工作目录:/build WORKDIR/build #将代码复制到容器中 COPY.. #将我们的代码编译成二进制可执行文件app RUNgobuild-oapp. ################### #接下来创建一个小镜像 ################### FROMscratch #从builder镜像中把/dist/app拷贝到当前目录 COPY--from=builder/build/app/ #需要运行的命令 ENTRYPOINT["/app"]

利用这一技术,我们剥离了使用golang:alpine作为编译映像来编译二进制可执行文件的过程,并基于scratch生成了一个简单且非常小的新映像。我们将二进制文件从名为builder的第一个映像复制到新创建的临时映像。更多关于刮刮镜的信息,请查看https://hub.docker.com/_/scratch.

附带其他文件的部署示例

这里以我之前的GoWeb视频教程中的小列表项目为例。该项目的Github仓库地址为:https://github.com/Q1mi/bubble.

如果项目中有静态文件或配置文件,需要将它们复制到最终的图像文件中。

我们的bubble项目使用静态文件和配置文件。具体目录结构如下:

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

我们需要将模板、静态和conf文件夹的内容复制到最终的图像文件中。更新后的Dockerfile文件如下

FROMgolang:alpineASbuilder #为我们的镜像设置必要的环境变量 ENVGO111MODULE=on\ CGO_ENABLED=0\ GOOS=linux\ GOARCH=amd64 #移动到工作目录:/build WORKDIR/build #复制项目中的go.mod和go.sum文件并下载依赖信息 COPYgo.mod. COPYgo.sum. RUNgomoddownload #将代码复制到容器中 COPY.. #将我们的代码编译成二进制可执行文件bubble RUNgobuild-obubble. ################### #接下来创建一个小镜像 ################### FROMscratch COPY./templates/templates COPY./static/static COPY./conf/conf #从builder镜像中把/dist/app拷贝到当前目录 COPY--from=builder/build/bubble/ #需要运行的命令 ENTRYPOINT["/bubble","conf/config.ini"]

简单来说就是多几个步骤复制。看看Dockerfile里的评论就知道了。

温馨提示:这里复制静态文件的步骤放在上层,COPY的二进制可执行文件放在下层,这样可以更多的利用缓存。

关联其他容器

因为我们的项目中使用了MySQL,所以我们可以选择用下面的命令启动一个MySQL容器,它的别名是mysql8019;root用户的密码是root1234;将容器中的/var/lib/mysql挂载到本地的/Users/q1mi/docker/mysql目录;内部服务端口是3306,它映射到外部端口13306。

dockerrun--namemysql8019-p13306:3306-eMYSQL_ROOT_PASSWORD=root1234-v/Users/q1mi/docker/mysql:/var/lib/mysql-dmysql:8.0.19

这里需要把我们程序中配置的MySQL的主机地址修改为容器别名,这样他们就可以通过别名(这里是mysql8019)进行内部通信了。

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

修改后记得重建bubble_app镜像:

dockerbuild.-tbubble_app

当我们在这里运行bubble_app容器时,需要使用-link将其与上面的mysql8019容器关联起来。具体命令如下:

dockerrun--link=mysql8019:mysql8019-p8888:8888bubble_app DockerCompose模式

除了如上使用-link关联两个容器之外,我们还可以使用DockerCompose来定义和运行多个容器。

Compose是一个定义和运行多容器Docker应用程序的工具。使用Compose,您可以使用YML文件来配置应用程序所需的所有服务。然后,通过一个命令,可以从YML文件配置中创建和启动所有服务。

使用Compose基本上是一个三步的过程:

  • 使用Dockerfile定义您的应用程序环境,以便它可以被复制到任何地方。
  • 定义组成应用程序docker-compose.yml的服务,以便它们可以在一个隔离的环境中一起运行。
  • 执行docker-composeup命令启动并运行整个应用程序。
  • 我们的项目需要两个容器来分别运行mysql和bubble_app。我们编写的docker-compose.yml文件的内容如下:

    #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.shmysql8019:3306--./bubble./conf/config.ini" depends_on: -mysql8019 ports: -"8888:8888"

    这个组合文件定义了两个服务:bubble_app和mysql8019。其中包括:

    bubble_app
    使用当前目录下的Dockerfile文件构建镜像,通过depends_on指定对mysql8019服务的依赖,声明服务端口8888,绑定外部端口8888。

    MySQL8019
    MySQL8019服务使用DockerHub的公共mysql:8.0.19镜像,内部端口3306,外部端口33061。

    这里需要注意的一点是,我们的bubble_app容器在尝试启动之前需要等待mysql8019容器正常启动,因为我们的web程序在启动时会初始化mysql连接。这里有两点需要改变。第一个是我们必须注释掉Dockerfile中的最后一句话:

    #Dockerfile ... #需要运行的命令(注释掉这一句,因为需要等MySQL启动之后再启动我们的Web程序) #ENTRYPOINT["/bubble","conf/config.ini"]

    第二个地方是在bubble_app下添加以下命令,在执行后续命令启动Web应用之前,使用事先编写的wait-for.sh脚本检查mysql8019:3306是否正常:

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

    当然,因为我们现在要在bubble_app镜像中执行sh命令,所以不能使用scratch镜像来构建。而是应该使用debian:stretch-slim,同时安装wait-for.sh脚本使用的netcat。最后,不要忘记将wait-for.sh脚本文件复制到最终映像中,并赋予它可执行的权限。更新后的Dockerfile内容如下:

    FROMgolang:alpineASbuilder #为我们的镜像设置必要的环境变量 ENVGO111MODULE=on\ CGO_ENABLED=0\ GOOS=linux\ GOARCH=amd64 #移动到工作目录:/build WORKDIR/build #复制项目中的go.mod和go.sum文件并下载依赖信息 COPYgo.mod. COPYgo.sum. RUNgomoddownload #将代码复制到容器中 COPY.. #将我们的代码编译成二进制可执行文件bubble RUNgobuild-obubble. ################### #接下来创建一个小镜像 ################### FROMdebian:stretch-slim COPY./wait-for.sh/ COPY./templates/templates COPY./static/static COPY./conf/conf #从builder镜像中把/dist/app拷贝到当前目录 COPY--from=builder/build/bubble/ RUNset-eux;\ apt-getupdate;\ apt-getinstall-y\ --no-install-recommends\ netcat;\ chmod755wait-for.sh #需要运行的命令 #ENTRYPOINT["/bubble","conf/config.ini"]

    所有条件准备就绪后,您可以执行以下命令来运行:

    docker-composeup

    完整的代码示例,请查看我的github库:https://github.com/Q1mi/deploy_bubble_using_docker.

    摘要

    使用Docker容器可以大大简化我们配置依赖环境的 *** 作,但同时也对我们的技术储备提出了更高的要求。无论你对Docker熟悉还是陌生,技术发展的车轮都在滚滚向前。

    参考链接:

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

    这就是这篇关于如何用Docker部署GoWeb应用程序的文章。有关Docker部署GoWeb的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!

    欢迎分享,转载请注明来源:内存溢出

    原文地址: https://outofmemory.cn/zz/774045.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-05-03
    下一篇 2022-05-03

    发表评论

    登录后才能评论

    评论列表(0条)

    保存