天天看点

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

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

<a target="_blank"></a>

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

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

<code>root@demohost:~# mkdir web-app</code>

<code>root@demohost:~# cd web-app/</code>

<code>root@demohost:~/web-app# vim.tiny main.go</code>

<code></code>

<code>package main</code>

<code>import (</code>

<code>"fmt"</code>

<code>"net/http"</code>

<code>)</code>

<code>func handler(w http.responsewriter, r *http.request) {</code>

<code>fmt.fprintf(w, "hello %s", r.url.path[1:])</code>

<code>}</code>

<code>func main() {</code>

<code>http.handlefunc("/world", handler)</code>

<code>http.listenandserve(":8080", nil)</code>

使用下面的命令运行上面的 “hello world” go 程序。在浏览器中输入<code>http://127.0.0.1:8080/world</code> 测试,你会在浏览器中看到 “hello world”。

<code>root@demohost:~/web-app# port=8080 go run main.go</code>

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

<code>root@demohost:~/web-app# vim.tiny dockerfile</code>

<code># 得到最新的 golang docker 镜像</code>

<code>from golang:latest</code>

<code># 在容器内部创建一个目录来存储我们的 web 应用,接着使它成为工作目录。</code>

<code>run mkdir -p /go/src/web-app</code>

<code>workdir /go/src/web-app</code>

<code># 复制 web-app 目录到容器中</code>

<code>copy . /go/src/web-app</code>

<code># 下载并安装第三方依赖到容器中</code>

<code>run go-wrapper download</code>

<code>run go-wrapper install</code>

<code># 设置 port 环境变量</code>

<code>env port 8080</code>

<code># 给主机暴露 8080 端口,这样外部网络可以访问你的应用</code>

<code>expose 8080</code>

<code># 告诉 docker 启动容器运行的命令</code>

<code>cmd ["go-wrapper", "run"]</code>

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

<code>root@demohost:~/web-app# docker build --rm -t web-app .</code>

<code>sending build context to docker daemon 3.584 kb</code>

<code>step 1 : from golang:latest</code>

<code>latest: pulling from library/golang</code>

<code>386a066cd84a: already exists</code>

<code>75ea84187083: pull complete</code>

<code>88b459c9f665: pull complete</code>

<code>a31e17eb9485: pull complete</code>

<code>1b272d7ab8a4: pull complete</code>

<code>eca636a985c1: pull complete</code>

<code>08158782d330: pull complete</code>

<code>digest: sha256:02718aef869a8b00d4a36883c82782b47fc01e774d0ac1afd434934d8ccfee8c</code>

<code>status: downloaded newer image for golang:latest</code>

<code>---&gt; 9752d71739d2</code>

<code>step 2 : run mkdir -p /go/src/web-app</code>

<code>---&gt; running in 9aef92fff9e8</code>

<code>---&gt; 49936ff4f50c</code>

<code>removing intermediate container 9aef92fff9e8</code>

<code>step 3 : workdir /go/src/web-app</code>

<code>---&gt; running in 58440a93534c</code>

<code>---&gt; 0703574296dd</code>

<code>removing intermediate container 58440a93534c</code>

<code>step 4 : copy . /go/src/web-app</code>

<code>---&gt; 82be55bc8e9f</code>

<code>removing intermediate container cae309ac7757</code>

<code>step 5 : run go-wrapper download</code>

<code>---&gt; running in 6168e4e96ab1</code>

<code>+ exec go get -v -d</code>

<code>---&gt; 59664b190fee</code>

<code>removing intermediate container 6168e4e96ab1</code>

<code>step 6 : run go-wrapper install</code>

<code>---&gt; running in e56f093b6f03</code>

<code>+ exec go install -v</code>

<code>web-app</code>

<code>---&gt; 584cd410fdcd</code>

<code>removing intermediate container e56f093b6f03</code>

<code>step 7 : env port 8080</code>

<code>---&gt; running in 298e2a415819</code>

<code>---&gt; c87fd2b43977</code>

<code>removing intermediate container 298e2a415819</code>

<code>step 8 : expose 8080</code>

<code>---&gt; running in 4f639a3790a7</code>

<code>---&gt; 291167229d6f</code>

<code>removing intermediate container 4f639a3790a7</code>

<code>step 9 : cmd go-wrapper run</code>

<code>---&gt; running in 6cb6bc28e406</code>

<code>---&gt; b32ca91bdfe0</code>

<code>removing intermediate container 6cb6bc28e406</code>

<code>successfully built b32ca91bdfe0</code>

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

<code>root@demohost:~/web-app# docker run -p 8080:8080 --name="test" -d web-app</code>

<code>7644606b9af28a3ef1befd926f216f3058f500ffad44522c1d4756c576cfa85b</code>

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

<code>### 列出所有容器</code>

<code>root@demohost:~/ docker ps -a</code>

<code>### 使用 id 启动容器</code>

<code>root@demohost:~/ docker start container_id_of_web_app</code>

<code>### 使用 id 停止容器</code>

<code>root@demohost:~/ docker stop container_id_of_web_app</code>

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

<code># 在容器内部创建一个目录来存储我们的 web 应用,接着使它称为工作目录。</code>

<code># 复制 web 程序到容器中</code>

<code>run go get github.com/codegangsta/gin</code>

<code>expose 3030</code>

<code># 启动容器时运行 gin</code>

<code>cmd gin run</code>

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

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

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

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

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

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

本文来自云栖社区合作伙伴“linux中国”

继续阅读