如何在Ubuntu 18.04上使用Docker和Nginx部署Go Web应用程序

介绍 (Introduction)

Docker is the most common containerization software used today. It enables developers to easily package apps along with their environments, which allows for quicker iteration cycles and better resource efficiency, while providing the same desired environment on each run. Docker Compose is a container orchestration tool that facilitates modern app requirements. It allows you to run multiple interconnected containers at the same time. Instead of manually running containers, orchestration tools give developers the ability to control, scale, and extend a container simultaneously.

Docker是当今使用的最常见的容器化软件。 它使开发人员可以轻松地将应用程序与其环境打包在一起,从而加快迭代周期并提高资源效率,同时在每次运行时提供相同的所需环境。 Docker Compose是一个容器编排工具,可满足现代应用程序的需求。 它允许您同时运行多个互连的容器。 编排工具代替了手动运行容器,而使开发人员能够同时控制,缩放和扩展容器。

The benefits of using Nginx as a front-end web server are its performance, configurability, and TLS termination, which frees the app from completing these tasks. The nginx-proxy is an automated system for Docker containers that greatly simplifies the process of configuring Nginx to serve as a reverse proxy. Its Let’s Encrypt add-on can accompany the nginx-proxy to automate the generation and renewal of certificates for proxied containers.

将Nginx用作前端Web服务器的好处是其性能,可配置性和TLS终止,这使该应用程序摆脱了完成这些任务的负担。 nginx-proxy是一个用于Docker容器的自动化系统,大大简化了将Nginx配置为充当反向代理的过程。 它的“ 让我们加密” 附加组件可以与nginx-proxy以自动生成和更新代理容器的证书。

In this tutorial, you will deploy an example Go web application with gorilla/mux as the request router and Nginx as the web server, all inside Docker containers, orchestrated by Docker Compose. You’ll use nginx-proxy with the Let’s Encrypt add-on as the reverse proxy. At the end of this tutorial, you will have deployed a Go web app accessible at your domain with multiple routes, using Docker and secured with Let’s Encrypt certificates.

在本教程中,您将部署一个示例Go Web应用程序,该应用程序将gorilla / mux作为请求路由器,将Nginx作为Web服务器,它们都在Docker容器内,由Docker Compose精心组织。 您将使用带有Let's Encrypt插件的nginx-proxy作为反向代理。 在本教程的最后,您将部署一个Go Web应用程序,该应用程序可以使用Docker在您的域中通过多个路由进行访问,并使用Let's Encrypt证书进行保护。

先决条件 (Prerequisites)

第1步-创建示例Go Web App (Step 1 — Creating an Example Go Web App)

In this step, you will set up your workspace and create a simple Go web app, which you’ll later containerize. The Go app will use the powerful gorilla/mux request router, chosen for its flexibility and speed.

在此步骤中,您将设置工作区并创建一个简单的Go Web应用程序,稍后将其容器化。 Go应用将使用强大的大猩猩/多路复用器请求路由器,该路由器因其灵活性和速度而选择。

Start off by logging in as sammy:

首先以sammy登录:

  • ssh sammy@your_server_ip

    ssh sammy @ your_server_ip

For this tutorial, you’ll store all data under ~/go-docker. Run the following command to do this:

对于本教程,您将所有数据存储在~/go-docker 。 运行以下命令以执行此操作:

  • mkdir ~/go-docker

    mkdir〜/ go-docker

Navigate to it:

导航到它:

  • cd ~/go-docker

    cd〜/ go-docker

You’ll store your example Go web app in a file named main.go. Create it using your text editor:

您会将示例Go Web应用程序存储在名为main.go的文件中。 使用您的文本编辑器创建它:

  • nano main.go

    纳米main.go

Add the following lines:

添加以下行:

main.go
main.go
package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "<h1>This is the homepage. Try /hello and /hello/Sammy\n</h1>")
    })

    r.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "<h1>Hello from Docker!\n</h1>")
    })

    r.HandleFunc("/hello/{name}", func(w http.ResponseWriter, r *http.Request) {
        vars := mux.Vars(r)
        title := vars["name"]

        fmt.Fprintf(w, "<h1>Hello, %s!\n</h1>", title)
    })

    http.ListenAndServe(":80", r)
}

You first import net/http and gorilla/mux packages, which provide HTTP server functionality and routing.

首先导入net/httpgorilla/mux软件包,它们提供HTTP服务器功能和路由。

The gorilla/mux package implements an easier and more powerful request router and dispatcher, while at the same time maintaining interface compatibility with the standard router. Here, you instantiate a new mux router and store it in variable r. Then, you define three routes: /, /hello, and /hello/{name}. The first (/) serves as the homepage and you include a message for the page. The second (/hello) returns a greeting to the visitor. For the third route (/hello/{name}) you specify that it should take a name as a parameter and show a greeting message with the name inserted.

gorilla/mux软件包实现了更轻松,功能更强大的请求路由器和调度程序,同时又保持了与标准路由器的接口兼容性。 在这里,您实例化了一个新的mux路由器,并将其存储在变量r 。 然后,定义三个路由: //hello/hello/{name} 。 第一个( / )用作主页,并且包含该页面的消息。 第二个( /hello )向访问者返回问候语。 对于第三条路由( /hello/{name} ),您指定它应使用名称作为参数并显示带有该名称的问候消息。

At the end of your file, you start the HTTP server with http.ListenAndServe and instruct it to listen on port 80, using the router you configured.

在文件末尾,使用http.ListenAndServe启动HTTP服务器,并指示它使用您配置的路由器在端口80上进行侦听。

Save and close the file.

保存并关闭文件。

Before running your Go app, you first need to compile and pack it for execution inside a Docker container. Go is a compiled language, so before a program can run, the compiler translates the programming code into executable machine code.

在运行Go应用之前,您首先需要对其进行编译和打包以在Docker容器中执行。 Go是一种编译语言 ,因此在程序运行之前,编译器会将编程代码转换为可执行的机器代码。

You’ve set up your workspace and created an example Go web app. Next, you will deploy nginx-proxy with an automated Let’s Encrypt certificate provision.

您已经设置了工作区并创建了一个示例Go Web应用程序。 接下来,您将使用自动的“我们加密”证书配置来部署nginx-proxy

第2步-使用“让我们加密”部署nginx-proxy (Step 2 — Deploying nginx-proxy with Let’s Encrypt)

It’s important that you secure your app with HTTPS. To accomplish this, you’ll deploy nginx-proxy via Docker Compose, along with its Let’s Encrypt add-on. This secures Docker containers proxied using nginx-proxy, and takes care of securing your app through HTTPS by automatically handling TLS certificate creation and renewal.

使用HTTPS保护应用程序很重要。 为此,您将通过Docker Compose以及其Let's Encrypt 插件部署nginx-proxy 。 这样可以保护使用nginx-proxy Docker容器,并通过自动处理TLS证书的创建和更新来确保通过HTTPS保护应用程序的安全。

You’ll be storing the Docker Compose configuration for nginx-proxy in a file named nginx-proxy-compose.yaml. Create it by running:

您将在一个名为nginx-proxy-compose.yaml的文件中存储nginx-proxy的Docker Compose配置。 通过运行以下命令创建它:

  • nano nginx-proxy-compose.yaml

    纳米nginx-proxy-compose.yaml

Add the following lines to the file:

将以下行添加到文件中:

nginx-proxy-compose.yaml
nginx-proxy-compose.yaml
version: '2'

services:
  nginx-proxy:
    restart: always
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/etc/nginx/vhost.d"
      - "/usr/share/nginx/html"
      - "/var/run/docker.sock:/tmp/docker.sock:ro"
      - "/etc/nginx/certs"

  letsencrypt-nginx-proxy-companion:
    restart: always
    image: jrcs/letsencrypt-nginx-proxy-companion
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    volumes_from:
      - "nginx-proxy"

Here you’re defining two containers: one for nginx-proxy and one for its Let’s Encrypt add-on (letsencrypt-nginx-proxy-companion). For the proxy, you specify the image jwilder/nginx-proxy, expose and map HTTP and HTTPS ports, and finally define volumes that will be accessible to the container for persisting Nginx-related data.

在这里,您将定义两个容器:一个用于nginx-proxy ,一个用于其Let's Encrypt附加组件( letsencrypt-nginx-proxy-companion )。 对于代理,您可以指定映像jwilder/nginx-proxy ,公开并映射HTTP和HTTPS端口,最后定义容器可访问的卷,以保留与Nginx相关的数据。

In the second block, you name the image for the Let’s Encrypt add-on configuration. Then, you configure access to Docker’s socket by defining a volume and then the existing volumes from the proxy container to inherit. Both containers have the restart property set to always, which instructs Docker to always keep them up (in the case of a crash or a system reboot).

在第二个块中,将图像命名为“让我们加密”附加组件配置。 然后,通过定义一个卷,然后定义要从代理容器继承的现有卷,来配置对Docker套接字的访问。 两个容器的restart属性都设置为always ,指示Docker始终保持它们(在崩溃或系统重启的情况下)。

Save and close the file.

保存并关闭文件。

Deploy the nginx-proxy by running:

通过运行以下命令部署nginx-proxy

  • docker-compose -f nginx-proxy-compose.yaml up -d

    docker -compose -f nginx-proxy-compose.yaml up -d

Docker Compose accepts a custom named file via the -f flag. The up command runs the containers, and the -d flag, detached mode, instructs it to run the containers in the background.

Docker Compose通过-f标志接受自定义的命名文件。 up命令运行容器,分离模式下的-d标志指示其在后台运行容器。

Your final output will look like this:

您的最终输出将如下所示:


   
   
Output
Creating network "go-docker_default" with the default driver Pulling nginx-proxy (jwilder/nginx-proxy:)... latest: Pulling from jwilder/nginx-proxy a5a6f2f73cd8: Pull complete 2343eb083a4e: Pull complete ... Digest: sha256:619f390f49c62ece1f21dfa162fa5748e6ada15742e034fb86127e6f443b40bd Status: Downloaded newer image for jwilder/nginx-proxy:latest Pulling letsencrypt-nginx-proxy-companion (jrcs/letsencrypt-nginx-proxy-companion:)... latest: Pulling from jrcs/letsencrypt-nginx-proxy-companion ... Creating go-docker_nginx-proxy_1 ... done Creating go-docker_letsencrypt-nginx-proxy-companion_1 ... done

You’ve deployed nginx-proxy and its Let’s Encrypt companion using Docker Compose. Next, you’ll create a Dockerfile for your Go web app.

您已经使用Docker Compose部署了nginx-proxy及其“让我们加密”伴侣。 接下来,您将为Go Web应用程序创建一个Dockerfile。

第3步-对Go Web App进行Docker化 (Step 3 — Dockerizing the Go Web App)

In this section, you will create a Dockerfile containing instructions on how Docker will create an immutable image for your Go web app. Docker builds an immutable app image—similar to a snapshot of the container—using the instructions found in the Dockerfile. The image’s immutability guarantees the same environment each time a container, based on the particular image, is run.

在本部分中,您将创建一个Dockerfile,其中包含有关Docker如何为Go Web应用程序创建不可变映像的说明。 Docker使用Dockerfile中的指令构建不可变的应用程序映像(类似于容器的快照)。 图像的不变性确保每次运行基于特定图像的容器时都具有相同的环境。

Create the Dockerfile with your text editor:

使用文本编辑器创建Dockerfile

  • nano Dockerfile

    纳米Dockerfile

Add the following lines:

添加以下行:

Dockerfile
Docker文件
FROM golang:alpine AS build
RUN apk --no-cache add gcc g++ make git
WORKDIR /go/src/app
COPY . .
RUN go get ./...
RUN GOOS=linux go build -ldflags="-s -w" -o ./bin/web-app ./main.go

FROM alpine:3.9
RUN apk --no-cache add ca-certificates
WORKDIR /usr/bin
COPY --from=build /go/src/app/bin /go/bin
EXPOSE 80
ENTRYPOINT /go/bin/web-app --port 80

This Dockerfile has two stages. The first stage uses the golang:alpine base, which contains pre-installed Go on Alpine Linux.

该Dockerfile有两个阶段。 第一阶段使用golang:alpine基础,其中包含在Alpine Linux上预安装的Go。

Then you install gcc, g++, make, and git as the necessary compilation tools for your Go app. You set the working directory to /go/src/app, which is under the default GOPATH. You also copy the content of the current directory into the container. The first stage concludes with recursively fetching the packages used from the code and compiling the main.go file for release without symbol and debug info (by passing -ldflags="-s -w"). When you compile a Go program it keeps a separate part of the binary that would be used for debugging, however, this extra information uses memory, and is not necessary to preserve when deploying to a production environment.

然后,安装gccg++makegit作为Go应用程序的必要编译工具。 您将工作目录设置为/go/src/app ,该目录位于默认的GOPATH下 。 您还将当前目录的内容复制到容器中。 第一阶段的结论是递归地从代码中获取使用的软件包,并编译main.go文件以在不包含符号和调试信息的情况下进行发布(通过传递-ldflags="-s -w" )。 当您编译Go程序时,它将保留二进制文件的单独部分,该二进制文件将用于调试,但是,这些额外的信息会占用内存,并且在部署到生产环境时不必保留。

The second stage bases itself on alpine:3.9 (Alpine Linux 3.9). It installs trusted CA certificates, copies the compiled app binaries from the first stage to the current image, exposes port 80, and sets the app binary as the image entry point.

第二阶段基于alpine:3.9 (Alpine Linux 3.9)。 它安装受信任的CA证书,将编译后的应用程序二进制文件从第一阶段复制到当前映像,公开端口80 ,然后将应用程序二进制文件设置为映像入口点。

Save and close the file.

保存并关闭文件。

You’ve created a Dockerfile for your Go app that will fetch its packages, compile it for release, and run it upon container creation. In the next step, you will create the Docker Compose yaml file and test the app by running it in Docker.

您已经为Go应用程序创建了一个Dockerfile,它将获取其程序包,对其进行编译以进行发布,并在创建容器时运行它。 在下一步中,您将创建Docker Compose yaml文件,并通过在Docker中运行它来测试应用程序。

步骤4 —创建和运行Docker Compose文件 (Step 4 — Creating and Running the Docker Compose File)

Now, you’ll create the Docker Compose config file and write the necessary configuration for running the Docker image you created in the previous step. Then, you will run it and check if it works correctly. In general, the Docker Compose config file specifies the containers, their settings, networks, and volumes that the app requires. You can also specify that these elements can start and stop as one at the same time.

现在,您将创建Docker Compose配置文件,并编写必要的配置以运行在上一步中创建的Docker映像。 然后,您将运行它并检查它是否正确运行。 通常,Docker Compose配置文件指定应用程序所需的容器,其设置,网络和卷。 您还可以指定这些元素可以同时作为一个开始和停止。

You will be storing the Docker Compose configuration for the Go web app in a file named go-app-compose.yaml. Create it by running:

您将把Go Web应用程序的Docker Compose配置存储在名为go-app-compose.yaml的文件中。 通过运行以下命令创建它:

  • nano go-app-compose.yaml

    纳米go-app-compose.yaml

Add the following lines to this file:

将以下行添加到此文件:

go-app-compose.yaml
go-app-compose.yaml
version: '2'
services:
  go-web-app:
    restart: always
    build:
      dockerfile: Dockerfile
      context: .
    environment:
      - VIRTUAL_HOST=example.com
      - LETSENCRYPT_HOST=example.com

Remember to replace example.com both times with your domain name. Save and close the file.

请记住两次都用您的域名替换example.com 。 保存并关闭文件。

This Docker Compose configuration contains one container (go-web-app), which will be your Go web app. It builds the app using the Dockerfile you’ve created in the previous step, and takes the current directory, which contains the source code, as the context for building. Furthermore, it sets two environment variables: VIRTUAL_HOST and LETSENCRYPT_HOST. nginx-proxy uses VIRTUAL_HOST to know from which domain to accept the requests. LETSENCRYPT_HOST specifies the domain name for generating TLS certificates, and must be the same as VIRTUAL_HOST, unless you specify a wildcard domain.

此Docker Compose配置包含一个容器( go-web-app ),它将成为您的Go Web应用程序。 它使用您在上一步中创建的Dockerfile来构建应用程序,并使用包含源代码的当前目录作为构建上下文。 此外,它设置了两个环境变量: VIRTUAL_HOSTLETSENCRYPT_HOSTnginx-proxy使用VIRTUAL_HOST知道从哪个域接受请求。 LETSENCRYPT_HOST指定用于生成TLS证书的域名,并且必须与VIRTUAL_HOST相同,除非您指定通配符域。

Now, you’ll run your Go web app in the background via Docker Compose with the following command:

现在,您将使用以下命令通过Docker Compose在后台运行Go Web应用程序:

  • docker-compose -f go-app-compose.yaml up -d

    docker-compose -f go-app-compose.yaml up -d

Your final output will look like the following:

您的最终输出将如下所示:


   
   
Output
Creating network "go-docker_default" with the default driver Building go-web-app Step 1/12 : FROM golang:alpine AS build ---> b97a72b8e97d ... Successfully tagged go-docker_go-web-app:latest WARNING: 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`. Creating go-docker_go-web-app_1 ... done

If you review the output presented after running the command, Docker logged every step of building the app image according to the configuration in your Dockerfile.

如果您查看运行命令后显示的输出,则Docker会根据Dockerfile中的配置记录构建应用程序映像的每个步骤。

You can now navigate to https://example.com/ to see your homepage. At your web app’s home address, you’re seeing the page as a result of the / route you defined in the first step.

您现在可以导航到https:// example.com /来查看您的主页。 在Web应用程序的家庭地址中,您会看到由于第一步中定义的/路由而导致的页面。

Now navigate to https://example.com/hello. You will see the message you defined in your code for the /hello route from Step 1.

现在导航到https:// example.com /hello 。 您将看到在代码中为步骤1中的/hello路由定义的消息。

Finally, try appending a name to your web app’s address to test the other route, like: https://example.com/hello/Sammy.

最后,尝试将名称附加到您的Web应用程序的地址以测试其他路由,例如: https:// example.com /hello/Sammy

Note: In the case that you receive an error about invalid TLS certificates, wait a few minutes for the Let’s Encrypt add-on to provision the certificates. If you are still getting errors after a short time, double check what you’ve entered against the commands and configuration shown in this step.

注意:如果您收到有关无效TLS证书的错误消息,请等待几分钟,让“加密”加载项提供证书。 如果短时间后仍然出现错误,请对照此步骤中显示的命令和配置仔细检查输入的内容。

You’ve created the Docker Compose file and written configuration for running your Go app inside a container. To finish, you navigated to your domain to check that the gorilla/mux router setup is serving requests to your Dockerized Go web app correctly.

您已经创建了Docker Compose文件并编写了配置,以在容器中运行Go应用。 最后,您导航到您的域以检查gorilla/mux路由器设置是否正确地向Dockerized Go网络应用提供了请求。

结论 (Conclusion)

You have now successfully deployed your Go web app with Docker and Nginx on Ubuntu 18.04. With Docker, maintaining applications becomes less of a hassle, because the environment the app is executed in is guaranteed to be the same each time it’s run. The gorilla/mux package has excellent documentation and offers more sophisticated features, such as naming routes and serving static files. For more control over the Go HTTP server module, such as defining custom timeouts, visit the official docs.

现在,您已在Ubuntu 18.04上成功使用Docker和Nginx部署了Go Web应用程序。 使用Docker,维护应用程序变得不再那么麻烦,因为保证了应用程序每次运行时所处的环境都是相同的。 gorilla / mux软件包提供了出色的文档,并提供了更复杂的功能,例如命名路由和提供静态文件。 要对Go HTTP服务器模块进行更多控制,例如定义自定义超时,请访问官方文档

翻译自: https://www.digitalocean.com/community/tutorials/how-to-deploy-a-go-web-application-with-docker-and-nginx-on-ubuntu-18-04

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值