如何在 Docker 中设置 Go 并部署应用

嗨,在本教程中,我们将学习如何使用 docker 部署 golang web 应用程序。 你可能已经知道,由于 golang 的高性能和可靠性,docker 是完全是用 golang 写的。在我们详细介绍之前,请确保你已经安装了 docker 以及 golang 并对它们有基本了解。

关于 docker

Docker 是一个开源程序,它可以将应用及其完整的依赖包捆绑到一起,并打包为容器,与宿主机共享相同的 Linux 内核。另一方面,像 VMware 这样的基于 hypervisor 的虚拟化操作系统容器提供了高级别的隔离和安全性,这是由于客户机和主机之间的通信是通过 hypervisor 来实现的,它们不共享内核空间。但是硬件仿真也导致了性能的开销,所以容器虚拟化诞生了,以提供一个轻量级的虚拟环境,它将一组进程和资源与主机以及其它容器分组及隔离,因此,容器内部的进程无法看到容器外部的进程或资源。

用 Go 语言创建一个 “Hello World” web 应用

首先我们为 Go 应用创建一个目录,它会在浏览器中显示 “Hello World”。创建一个 web-app 目录并使它成为当前目录。进入 web-app 应用目录并编辑一个名为 main.go 的文件。


  1. root@demohost:~# mkdir web-app
  2. root@demohost:~# cd web-app/
  3. root@demohost:~/web-app# vim.tiny main.go
  4. package main
  5. import (
  6. "fmt"
  7. "net/http"
  8. )
  9. func handler(w http.ResponseWriter, r *http.Request) {
  10. fmt.Fprintf(w, "Hello %s", r.URL.Path[1:])
  11. }
  12. func main() {
  13. http.HandleFunc("/World", handler)
  14. http.ListenAndServe(":8080", nil)
  15. }

使用下面的命令运行上面的 “Hello World” Go 程序。在浏览器中输入http://127.0.0.1:8080/World 测试,你会在浏览器中看到 “Hello World”。


  1. root@demohost:~/web-app# PORT=8080 go run main.go

下一步是将上面的应用在 docker 中容器化。因此我们会创建一个 dockerfile 文件,它会告诉 docker 如何容器化我们的 web 应用。


  1. root@demohost:~/web-app# vim.tiny Dockerfile
  2. # 得到最新的 golang docker 镜像
  3. FROM golang:latest
  4. # 在容器内部创建一个目录来存储我们的 web 应用,接着使它成为工作目录。
  5. RUN mkdir -p /go/src/web-app
  6. WORKDIR /go/src/web-app
  7. # 复制 web-app 目录到容器中
  8. COPY . /go/src/web-app
  9. # 下载并安装第三方依赖到容器中
  10. RUN go-wrapper download
  11. RUN go-wrapper install
  12. # 设置 PORT 环境变量
  13. ENV PORT 8080
  14. # 给主机暴露 8080 端口,这样外部网络可以访问你的应用
  15. EXPOSE 8080
  16. # 告诉 Docker 启动容器运行的命令
  17. CMD ["go-wrapper", "run"]

构建/运行容器

使用下面的命令构建你的 Go web-app,你会在成功构建后获得确认。


  1. root@demohost:~/web-app# docker build --rm -t web-app .
  2. Sending build context to Docker daemon 3.584 kB
  3. Step 1 : FROM golang:latest
  4. latest: Pulling from library/golang
  5. 386a066cd84a: Already exists
  6. 75ea84187083: Pull complete
  7. 88b459c9f665: Pull complete
  8. a31e17eb9485: Pull complete
  9. 1b272d7ab8a4: Pull complete
  10. eca636a985c1: Pull complete
  11. 08158782d330: Pull complete
  12. Digest: sha256:02718aef869a8b00d4a36883c82782b47fc01e774d0ac1afd434934d8ccfee8c
  13. Status: Downloaded newer image for golang:latest
  14. ---> 9752d71739d2
  15. Step 2 : RUN mkdir -p /go/src/web-app
  16. ---> Running in 9aef92fff9e8
  17. ---> 49936ff4f50c
  18. Removing intermediate container 9aef92fff9e8
  19. Step 3 : WORKDIR /go/src/web-app
  20. ---> Running in 58440a93534c
  21. ---> 0703574296dd
  22. Removing intermediate container 58440a93534c
  23. Step 4 : COPY . /go/src/web-app
  24. ---> 82be55bc8e9f
  25. Removing intermediate container cae309ac7757
  26. Step 5 : RUN go-wrapper download
  27. ---> Running in 6168e4e96ab1
  28. + exec go get -v -d
  29. ---> 59664b190fee
  30. Removing intermediate container 6168e4e96ab1
  31. Step 6 : RUN go-wrapper install
  32. ---> Running in e56f093b6f03
  33. + exec go install -v
  34. web-app
  35. ---> 584cd410fdcd
  36. Removing intermediate container e56f093b6f03
  37. Step 7 : ENV PORT 8080
  38. ---> Running in 298e2a415819
  39. ---> c87fd2b43977
  40. Removing intermediate container 298e2a415819
  41. Step 8 : EXPOSE 8080
  42. ---> Running in 4f639a3790a7
  43. ---> 291167229d6f
  44. Removing intermediate container 4f639a3790a7
  45. Step 9 : CMD go-wrapper run
  46. ---> Running in 6cb6bc28e406
  47. ---> b32ca91bdfe0
  48. Removing intermediate container 6cb6bc28e406
  49. Successfully built b32ca91bdfe0

现在可以运行我们的 web-app 了,可以执行下面的命令。


  1. root@demohost:~/web-app# docker run -p 8080:8080 --name="test" -d web-app
  2. 7644606b9af28a3ef1befd926f216f3058f500ffad44522c1d4756c576cfa85b

进入 http://localhost:8080/World 浏览你的 web 应用。你已经成功容器化了一个可重复的/确定性的 Go web 应用。使用下面的命令来启动、停止并检查容器的状态。


  1. ### 列出所有容器
  2. root@demohost:~/ docker ps -a
  3. ### 使用 id 启动容器
  4. root@demohost:~/ docker start CONTAINER_ID_OF_WEB_APP
  5. ### 使用 id 停止容器
  6. root@demohost:~/ docker stop CONTAINER_ID_OF_WEB_APP

重新构建镜像

假设你正在开发 web 应用程序并在更改代码。现在要在更新代码后查看结果,你需要重新生成 docker 镜像、停止旧镜像并运行新镜像,并且每次更改代码时都要这样做。为了使这个过程自动化,我们将使用 docker 卷在主机和容器之间共享一个目录。这意味着你不必为在容器内进行更改而重新构建镜像。容器如何检测你是否对 web 程序的源码进行了更改?答案是有一个名为 “Gin” 的好工具https://github.com/codegangsta/gin,它能检测是否对源码进行了任何更改,然后重建镜像/二进制文件并在容器内运行更新过代码的进程。

要使这个过程自动化,我们将编辑 Dockerfile 并安装 Gin 将其作为入口命令来执行。我们将开放 3030端口(Gin 代理),而不是 8080。 Gin 代理将转发流量到 web 程序的 8080 端口。


  1. root@demohost:~/web-app# vim.tiny Dockerfile
  2. # 得到最新的 golang docker 镜像
  3. FROM golang:latest
  4. # 在容器内部创建一个目录来存储我们的 web 应用,接着使它称为工作目录。
  5. RUN mkdir -p /go/src/web-app
  6. WORKDIR /go/src/web-app
  7. # 复制 web 程序到容器中
  8. COPY . /go/src/web-app
  9. # 下载并安装第三方依赖到容器中
  10. RUN go get github.com/codegangsta/gin
  11. RUN go-wrapper download
  12. RUN go-wrapper install
  13. # 设置 PORT 环境变量
  14. ENV PORT 8080
  15. # 给主机暴露 8080 端口,这样外部网络可以访问你的应用
  16. EXPOSE 3030
  17. # 启动容器时运行 Gin
  18. CMD gin run
  19. # 告诉 Docker 启动容器运行的命令
  20. CMD ["go-wrapper", "run"]

现在构建镜像并启动容器:


  1. root@demohost:~/web-app# docker build --rm -t web-app .

我们会在当前 web 程序的根目录下运行 docker,并通过暴露的 3030 端口链接 CWD (当前工作目录)到容器中的应用目录下。


  1. root@demohost:~/web-app# docker run -p 3030:3030 -v `pwd`:/go/src/web-app --name="test" -d web-app

打开 http://localhost:3030/World, 你就能看到你的 web 程序了。现在如果你改变了任何代码,会在浏览器刷新后反映在你的浏览器中。

总结

就是这样,我们的 Go web 应用已经运行在 Ubuntu 16.04 Docker 容器中运行了!你可以通过使用 Go 框架来快速开发 API、网络应用和后端服务,从而扩展当前的网络应用。

原文发布时间为:2017-01-12

本文来自合作伙伴“Linux中国”

时间: 2024-07-31 01:08:26

如何在 Docker 中设置 Go 并部署应用的相关文章

如何在word中设置不连续的页码?

有些word封面不需要页码,目录需要一个从第一页开始的页码,正文需要一个从第一页开始的页码.如果在页眉页脚插入页码,会得到连续的页码编号,这样不符合我们的要求. 那么如何在word中设置不连续的页码呢?举个例子:某word文档,前两页是目录,从第三页起是正文. 大体的思路是:想办法把目录和正文分成两个独立的部分,然后给目录设置一个页码,给正文设置一个页码就可以了. 操作方法是: 1.首先,将光标移至第二页的最后,点击插入分隔符分节符类型中选择下一页,然后点击视图打开页眉与页脚工具条; 2.将光标

华硕笔记本预装win8改win7如何在bios中设置

  华硕笔记本预装win8改win7如何在bios中设置         开机按F2键,进入bios 切换到Security标签,找到Secure BOOT Control,将Enabled改为Disabled,这一步的作用是关闭微软的Secure BOOT,这个功能开启会导致不能识别U盘启动系统的安装 切换到BOOT标签,将Launch CSM改为Enabled(如果是灰色不可以选择,先按F10保存退出再次进入就可以选择了),这个选项的作用就是,将UEFI的BIOS改为传统BIOS 最后按 F

联想G410(预装windows8.1) 如何在bios中设置从U盘启动安装Ubuntu14.10?

问题描述 联想G410(预装windows8.1) 如何在bios中设置从U盘启动安装Ubuntu14.10? 我已经将U盘制作成了安装盘,如图 然后重启电脑,按fn+f2进入了bios设置界面, 如何设置从U盘启动呢? 解决方案 看不到图片啊,你重新发一下图吧 解决方案二: 看不到图片啊,你重新发一下图吧 解决方案三: 首先把boot mode由uefi修改为传统或者bios. 然后下面设置启动顺序,如果没有,开机按住f8或者f12,然后会有启动设备列表的菜单,选择U盘. 解决方案四: bio

ios-如何在cell中设置cell不能点击(不是在TableView中在设置)

问题描述 如何在cell中设置cell不能点击(不是在TableView中在设置) 如何在cell中设置cell不能点击(不是在TableView中在设置) 解决方案 将cell的交互关掉 解决方案二: cell.userInteractionEnabled = No; 解决方案三: cell.selectionStyle = UITableViewCellSelectionStyleNone; 是没有选中效果,还是可以点击的 解决方案四: 将cell的交互关掉 将cell的交互关掉 将cell

如何在Docker中使用Open vSwitch

Open vSwitch是一个虚拟交换软件,主要用于虚拟机VM环境,提供网络的虚拟化.本篇文档重点介绍如何在Docker中使用Open vSwitch. 这个文档描述了如何在Docker(大于或等于1.9.0版本)中使用Open vSwitch.我们假设你已经安装好了Open vSwitch和Docker.请没有安装好的读者可以根据INSTALL.md和www.docker.com的说明来进行安装. Docker 1.9.0开始支持多主机网络(multi-host networking).我们可

android如何在fragment中设置屏幕的上半部分区域有触摸事件?

问题描述 android如何在fragment中设置屏幕的上半部分区域有触摸事件? 我设置了一个swiperefreshlistview,但是列表刷新的touch方法跟列表的滑动冲突了,请问下在fragment中怎么设置区域监听的 解决方案 列表布局是占满整个fragment么?如果不是的话,可以在xml布局中对部分区域设置点击无效,如果是占满fragment的话,但是想对其中一块区域监听,那就直接在代码中判断是否在那个区域范围内再做操作了 解决方案二: 在fragment上部分添加一个view

如何在 android 中设置一个用户名和密码文件

问题描述 如何在 android 中设置一个用户名和密码文件 我设置了两个edittext和一个button.我想设置一个特殊的用户名和密码,当我点击按钮时,如果用户名和密码正确,就会打开一个新的intent,否则显示一个toast.我用的下面的代码显示不同的toast,但是没有运行出来,总是显示 ""incorrect"".如何解决这个问题呢? b.setOnClickListener(new OnClickListener() { public void onC

Linux有问必答:如何在curl中设置自定义的HTTP头

Linux有问必答:如何在curl中设置自定义的HTTP头 问题:我正尝试使用curl命令获取一个URL,但除此之外我还想在传出的HTTP请求中设置一些自定义的头部字段.我如何能够在curl中使用自定义的HTTP头呢? curl是一个强大的命令行工具,它可以通过网络将信息传递给服务器或者从服务器获取数据.他支持很多的传输协议,尤其是HTTP/HTTPS以及其他诸如FTP/FTPS, RTSP, POP3/POP3S, SCP, IMAP/IMAPS协议等.当你使用curl向一个URL发送HTTP

iis6-关于IIS里,如何在 .htaccess 中设置浏览者不能访问某个目录

问题描述 关于IIS里,如何在 .htaccess 中设置浏览者不能访问某个目录 .htaccess中,只有一句RewriteProxy (.*) http://120.41.89.88/abcd/$1 [NC,U] 也就是把网站解析到一个新的服务器链接地址上,如何写语句禁止用户访问http://120.41.89.88:8624/abcd/HTML/这个子目录?