_ 作者选择了 免费和开源基金作为 写给捐款计划的一部分接受捐款。
介绍
[Docker] (https://www.docker.com/)是一款常用的容器化软件,使开发者能够轻松地随其环境一起包装应用软件,允许更快的迭代周期和更好的资源效率,同时在每次运行时提供同样理想的环境. [Docker Confose] (https://docs.docker.com/compose/)是便利现代应用要求的容器管弦乐工具. 它允许您同时运行多个互联的容器. 管弦乐工具不是手工操作的容器,而是赋予开发者同时控制,缩放,并扩展容器的能力.
使用Nginx作为前端网络服务器的好处在于性能,可配置性,以及TLS终止,这让应用程序可以自由完成这些任务. nginx-proxy是多克容器的自动化系统,简化了将Nginx配置为倒置代用的程序. 它让我们加密[接 (https://github.com/nginx-proxy/acme-companion)可以伴随"nginx-proxy"自动生成并更新代用容器证书.
在本教程中,您将部署一个 Go Web 应用程序的示例 gorilla/mux作为请求路由器和 Nginx 作为 Web 服务器,所有这些都是由 Docker Compose 主办的 Docker 容器。您将使用 nginx-proxy
与 Let's Encrypt 插件作为反向代理程序。本教程结束时,您将部署一个 Go Web 应用程序,可在您的域名上使用多个路由,使用 Docker 并使用 Let's Encrypt 证书。
前提条件
- Ubuntu 22.04 有根权限的服务器,以及一个二级非根账户. 您可以按照 [此初始服务器设置指南] (https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-22-04) 设置此设置 。 对于这个教程,非根基用户是`Sammy'。
- Docker通过遵循如何在Ubuntu 22.04上安装Docker的前两个步骤而安装.
- Docker 作曲,通过遵循[如何在Ubuntu 22.04上安装 Docker 作曲 (https://andsky.com/tech/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-22-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
套件实现了更强大的请求路由器和发送器,同时保持与标准路由器的接口兼容性。
然后,您定义了三个路径: /
, /hello
,和 /hello/{name}
. 第一条路径(/
)作为主页,您添加了该页面的消息。 第二条路径(/hello
)向访问者返回问候。
在文件的末尾,您将启动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: '3'
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通过)指示它在背景中运行容器。
你会收到这样的输出:
1[secondary_label Output]
2[+] Running 21/21
3 ⠿ letsencrypt-nginx-proxy-companion Pulled 6.8s
4 ⠿ df9b9388f04a Pull complete 3.1s
5 ⠿ 6c6cfd4eaf5b Pull complete 3.9s
6 ⠿ 870307501973 Pull complete 4.3s
7 ⠿ e8ff3435d14f Pull complete 4.5s
8 ⠿ 5b78ba945919 Pull complete 4.8s
9 ⠿ 973b2ca26006 Pull complete 5.0s
10 ⠿ nginx-proxy Pulled 8.1s
11 ⠿ 42c077c10790 Pull complete 3.9s
12 ⠿ 62c70f376f6a Pull complete 5.5s
13 ⠿ 915cc9bd79c2 Pull complete 5.6s
14 ⠿ 75a963e94de0 Pull complete 5.7s
15 ⠿ 7b1fab684d70 Pull complete 5.7s
16 ⠿ db24d06d5af4 Pull complete 5.8s
17 ⠿ e917373dbecf Pull complete 5.9s
18 ⠿ 11e2be9775e9 Pull complete 5.9s
19 ⠿ 9996fa75bc02 Pull complete 6.1s
20 ⠿ d37674efdf77 Pull complete 6.3s
21 ⠿ a45d84576e75 Pull complete 6.3s
22 ⠿ a13c1f42faf7 Pull complete 6.4s
23 ⠿ 4f4fb700ef54 Pull complete 6.5s
24[+] Running 3/3
25 ⠿ Network go-docker_default Created 0.1s
26 ⠿ Container go-docker-nginx-proxy-1 Started 0.5s
27 ⠿ Container go-docker-letsencrypt-nginx-proxy-companion-1 Started 0.8s
您已经部署了「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.17
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: '3'
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/13 : FROM golang:alpine AS build
5 ---> b97a72b8e97d
6...
7Successfully built 71e4b1ef2e25
8Successfully tagged go-docker_go-web-app:latest
9...
10[+] Running 1/1
11 ⠿ Container go-docker-go-web-app-1 Started
如果您在运行命令后审查所示的输出,Docker 会根据您的Dockerfile中的配置记录构建应用程序图像的每个步骤。
您现在可以导航到 https://your_domain/
访问您的主页. 在您的 Web 应用程序的首页地址,您可以访问该页面,因为您在第一步中定义的 /
路线。
现在导航到 https://your_domain/hello
. 您在您的代码中定义的 /hello
路由从步骤 1 将加载。
最后,添加一个名称到您的Web应用程序的地址来测试其他路线,例如: https://your_domain/hello/Sammy
。
注意: 如果您收到有关无效的 TLS 证书的错误,请等待几分钟,让 Let's Encrypt 插件提供证书。
您已创建了 Docker Compose 文件和编写的配置,以便在容器中运行您的 Go 应用程序. 最后,您导航到您的域,以检查gorilla/mux
路由器设置是否正确地向您的 Dockerized Go Web 应用程序提供请求。
结论
你现在已经成功部署 在Ubuntu22.04上与多克和Nginx一起去网络应用. 与多克一起,维护应用程序并不那么花时间,因为应用程序被执行的环境保证每次运行时都会是相同的. gorilla/mux包有出色的文档,并提供更精密的特征,例如命名路线并服务静态文件. 对于Go HTTP 服务器模块的更多控制,例如定义自定义超时,访问official docs.