_ 作者选择了 免费和开源基金作为 写给捐款计划的一部分接受捐款。
介绍
[Docker] (https://www.docker.com/)是当今最常用的集装箱化软件. 它使开发者能够轻松地将应用与其环境一起包装,从而可以更快地进行迭代循环并提高资源效率,同时在每次运行中提供同样理想的环境. [Docker Confose] (https://docs.docker.com/compose/)是便利现代应用要求的容器管弦乐工具. 它允许您同时运行多个互联的容器. 管弦乐工具不是手工操作的容器,而是赋予开发者同时控制,缩放,并扩展容器的能力.
将Nginx作为前端网络服务器的好处是它的性能,可配置性,以及TLS终止,这使得应用程序可以自由完成这些任务. nginx-proxy是多克容器的自动化系统,它大大简化了Nginx的配置过程,作为倒置代用. 它让我们加密[接 (https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion)可以伴随"nginx-proxy"自动生成并更新代用容器证书.
在本教程中,您将部署一个 Go Web 应用程序的示例 gorilla/mux作为请求路由器和 Nginx 作为 Web 服务器,所有在 Docker 容器内,由 Docker Compose 组织。您将使用 nginx-proxy
与 Let's Encrypt 插件作为反向代理程序。本教程结束时,您将部署一个 Go Web 应用程序,可在您的域名上使用多个路由,使用 Docker 和安全使用 Let's Encrypt 证书。
前提条件
- 具有根权限的Ubuntu 18.04服务器,以及一个二级的非根账户。 您可以按照 [此初始服务器设置指南] (https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-18-04) 设置此设置 。 对于这个教程,非根本用户是`Sammy'。
- Docker是通过如何在Ubuntu 18.04上安装Docker的前两个步骤而安装的.
- Docker 编曲是通过[如何在Ubuntu 18.04上安装Docker 编曲(https://andsky.com/tech/tutorials/how-to-install-docker-compose-on-ubuntu-18-04)的第一步而安装的.
- 一个完全注册的域名。 此教程将始终使用
您的域
。 您可以在 [Freenom] (https://www.freenom.com/en/index.html?lang=en] 上免费获取, 或者使用您选择的域注册员 。 - DNS"A"记录有"你的域"指向您服务器的公开IP地址. 您可以跟随 [此介绍] (https://www.digitalocean.com/docs/networking/dns/quickstart/)到 DigitalOcean DNS 了解如何添加这些内容的细节.
- 联合国 对多克及其建筑的理解. 关于多克的介绍,见多克生态系统:共同组成部分介绍。 .
步骤 1 — 创建一个示例Go Web App
在此步骤中,您将设置您的工作空间,并创建一个简单的GoWeb应用程序,您将随后集装。Go应用程序将使用强大的 gorilla/mux请求路由器,其灵活性和速度选择。
对于本教程,您将存储所有数据在~/go-docker
下,运行以下命令来执行此操作:
1mkdir ~/go-docker
导航它:
1cd ~/go-docker
您将您的示例 Go Web 应用程序存储在名为 main.go 的文件中. 使用文本编辑器创建它:
1nano main.go
添加以下几行:
1[label ~/go-docker/main.go]
2package main
3
4import (
5 "fmt"
6 "net/http"
7
8 "github.com/gorilla/mux"
9)
10
11func main() {
12 r := mux.NewRouter()
13
14 r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
15 fmt.Fprintf(w, "<h1>This is the homepage. Try /hello and /hello/Sammy\n</h1>")
16 })
17
18 r.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
19 fmt.Fprintf(w, "<h1>Hello from Docker!\n</h1>")
20 })
21
22 r.HandleFunc("/hello/{name}", func(w http.ResponseWriter, r *http.Request) {
23 vars := mux.Vars(r)
24 title := vars["name"]
25
26 fmt.Fprintf(w, "<h1>Hello, %s!\n</h1>", title)
27 })
28
29 http.ListenAndServe(":80", r)
30}
您首先导入net/http
和gorilla/mux
包,这些包提供 HTTP 服务器功能和路由。
‘gorilla/mux'软件包执行一个更简单更强大的请求路由器和调度器,同时保持与标准路由器的接口相容性. 在这里,你即用一个新的 " mux " 路由器并将其存储在可变 " r " 中。 然后,你定义了三条路线:/'、
/hello'和/hello/{name}
'。 第一页( " / " )作为主页,其中包含该页的信息。 第二个( " /hello " )向来访者问候。 对于第三条路由(/hello/{name}
>),您指定它应该取出一个名称作为参数,并显示带有所插入名称的问候信息.
在文件的末尾,您将启动HTTP服务器以http.ListenAndServe
,并指示它在端口80
上聆听,使用您配置的路由器。
保存并关闭文件。
在运行 Go 应用程序之前,您需要先编译并在 Docker 容器内执行。 Go 是一个 编译语言,因此在一个程序可以运行之前,编译器将编程代码翻译成可执行的机器代码。
您已经设置了工作区并创建了一个示例 Go Web 应用程序,接下来,您将部署nginx-proxy
与自动的 Let's Encrypt 证书提供。
步骤 2 — 使用 Let's Encrypt 部署 nginx 代理
要做到这一点,您将通过 Docker Compose 部署「nginx-proxy」,以及其 Let's Encrypt add-on。
您将将nginx-proxy
的Docker Compose配置存储在名为nginx-proxy-compose.yaml
的文件中。
1nano nginx-proxy-compose.yaml
将以下行添加到文件中:
1[label ~/go-docker/nginx-proxy-compose.yaml]
2version: '2'
3
4services:
5 nginx-proxy:
6 restart: always
7 image: jwilder/nginx-proxy
8 ports:
9 - "80:80"
10 - "443:443"
11 volumes:
12 - "/etc/nginx/vhost.d"
13 - "/usr/share/nginx/html"
14 - "/var/run/docker.sock:/tmp/docker.sock:ro"
15 - "/etc/nginx/certs"
16
17 letsencrypt-nginx-proxy-companion:
18 restart: always
19 image: jrcs/letsencrypt-nginx-proxy-companion
20 volumes:
21 - "/var/run/docker.sock:/var/run/docker.sock:ro"
22 volumes_from:
23 - "nginx-proxy"
在这里,你定义了两个容器:一个为).对于代理,你指定图像jwilder/nginx-proxy
,曝光和地图 HTTP 和 HTTPS 端口,最后定义将可访问容器的卷,以便持久的 Nginx 相关数据。
在第二个块中,您将为 Let's Encrypt 插件配置命名图像。然后,您将通过定义一个卷来配置访问 Docker 插件,然后从代理容器继承现有的卷。
保存并关闭文件。
通过运行nginx-proxy
部署:
1docker-compose -f nginx-proxy-compose.yaml up -d
Docker Compose通过-f
旗声接受一个自定义名为的文件. up
命令运行容器,而-d
旗帜,分离模式,指示它在背景中运行容器。
你的最终结果将是这样的:
1[secondary_label Output]
2Creating network "go-docker_default" with the default driver
3Pulling nginx-proxy (jwilder/nginx-proxy:)...
4latest: Pulling from jwilder/nginx-proxy
5a5a6f2f73cd8: Pull complete
62343eb083a4e: Pull complete
7...
8Digest: sha256:619f390f49c62ece1f21dfa162fa5748e6ada15742e034fb86127e6f443b40bd
9Status: Downloaded newer image for jwilder/nginx-proxy:latest
10Pulling letsencrypt-nginx-proxy-companion (jrcs/letsencrypt-nginx-proxy-companion:)...
11latest: Pulling from jrcs/letsencrypt-nginx-proxy-companion
12...
13Creating go-docker_nginx-proxy_1 ... done
14Creating go-docker_letsencrypt-nginx-proxy-companion_1 ... done
您已经部署了「nginx-proxy」及其使用 Docker Compose 的 Let's Encrypt 伴侣,接下来,您将为您的 Go Web 应用程序创建 Dockerfile。
步骤 3 – 对 Go Web App 进行 Dockerizing
在本节中,您将创建一个 Dockerfile,其中包含有关 Docker 如何为 Go Web 应用程序创建不变图像的说明。
使用您的文本编辑器创建Dockerfile
:
1nano Dockerfile
添加以下几行:
1[label ~/go-docker/Dockerfile]
2FROM golang:alpine AS build
3RUN apk --no-cache add gcc g++ make git
4WORKDIR /go/src/app
5COPY . .
6RUN go mod init webserver
7RUN go mod tidy
8RUN GOOS=linux go build -ldflags="-s -w" -o ./bin/web-app ./main.go
9
10FROM alpine:3.13
11RUN apk --no-cache add ca-certificates
12WORKDIR /usr/bin
13COPY --from=build /go/src/app/bin /go/bin
14EXPOSE 80
15ENTRYPOINT /go/bin/web-app --port 80
此 Dockerfile 有兩個階段. 第一個階段使用了「golang:alpine」基礎,其中包含在 Alpine Linux 上預先安裝的 Go。
然后安装 " gcc " 、 " gQ " 、 " make " 和 " git " 作为必要的汇编工具。 去应用。 您将工作目录设置为) 。 您还将当前目录的内容复制到容器中 。 第一阶段最后从代码中递归取出所使用的包并编译出"main.go"文件,无符号发布并调试信息(通过"-ldflags="-s-w"). 当您编译一个 Go 程序时, 它会保留一个单独的二进制部分, 用于调试, 然而, 这个额外信息会使用内存, 并且在部署到生产环境时不需要保存 .
第二阶段基于)。它安装了可信的CA证书,将编译的应用程序二进制从第一阶段复制到当前图像,暴露了端口80
,并将应用程序二进制设置为图像输入点。
保存并关闭文件。
您已经为您的 Go 应用程序创建了 Dockerfile,该应用程序将收集其包,编译用于发布,并在创建容器时运行它。
第4步:创建和运行Docker组件文件
现在,您将创建 Docker Compose 配置文件并写入您在上一步创建的 Docker 图像运行所需的配置,然后,您将运行它并检查它是否正常工作。
您将为 Go Web 应用程序存储 Docker Compose 配置到名为 go-app-compose.yaml
的文件中。
1nano go-app-compose.yaml
将以下行添加到此文件中:
1[label ~/go-docker/go-app-compose.yaml]
2version: '2'
3services:
4 go-web-app:
5 restart: always
6 build:
7 dockerfile: Dockerfile
8 context: .
9 environment:
10 - VIRTUAL_HOST=your_domain
11 - LETSENCRYPT_HOST=your_domain
请记住,两次都用您的域名替换 your_domain
. 保存并关闭文件。
这个 Docker 编译配置包含一个容器( ) , 它将是您的 去网络应用。 它使用您在前一步所创建的 Dockerfile 构建应用程序,并以包含源代码的当前目录作为构建的上下文. 此外,它规定了两个环境变量:VIRTUAL-HOST ' 和
LETSENCRYPT-HOST ' 。 LETSENCRYPT-Host' 指定生成 TLS 证书的域名,并且必须与
VIRTUAL-Host'相同,除非您指定了通配符域.
现在,您将通过 Docker Compose 在背景中运行 Go Web 应用程序,使用以下命令:
1docker-compose -f go-app-compose.yaml up -d
你的最终结果将如下:
1[secondary_label Output]
2Creating network "go-docker_default" with the default driver
3Building go-web-app
4Step 1/12 : FROM golang:alpine AS build
5 ---> b97a72b8e97d
6...
7Successfully tagged go-docker_go-web-app:latest
8WARNING: Image for service go-web-app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
9Creating go-docker_go-web-app_1 ... done
如果您在运行该命令后审查所示的输出,Docker 会根据您的Dockerfile中的配置记录构建应用程序图像的每个步骤。
您现在可以导航到 https://your_domain/
查看您的主页. 在您的 Web 应用程序的主地址,您正在看到页面作为您在第一步中定义的 /
路线的结果。
现在导航到 https://your_domain/hello
. 您将从步骤 1 看到您在代码中定义的 /hello
路线的消息。
最后,尝试将一个名称添加到您的 Web 应用程序的地址,以测试其他路径,例如: https://your_domain/hello/Sammy
。
注意: 如果您收到有关无效的 TLS 证书的错误,请等待几分钟,让 Let's Encrypt 插件提供证书。
您已创建了 Docker Compose 文件和编写的配置,以便在容器内运行您的 Go 应用程序. 最后,您导航到您的域,以检查gorilla/mux
路由器设置是否正确地向您的 Dockerized Go Web 应用程序发送请求。
结论
你现在已经成功部署 Go web app with Docker and Nginx on Ubuntu 18.04 (英语). 和多克一起,维持应用程序变得不那么麻烦了,因为每次运行时,被执行的应用程序所处环境保证是相同的. gorilla/mux包有出色的文档,并提供更精密的特征,例如命名路线并服务静态文件. 对于Go HTTP 服务器模块的更多控制,例如定义自定义超时,访问official docs.