Bereitstellen einer Go-Webanwendung mit Docker und Nginx unter Ubuntu 18.04

Der Autor hat den Free and Open Source Fund ausgewählt, um eine Spende als Teil des Write for DOnations zu erhalten. Programm.

Einführung

Docker ist die heute am häufigsten verwendete Containerisierungssoftware. Entwickler können auf einfache Weise Apps zusammen mit ihren Umgebungen paketieren, was schnellere Iterationszyklen und eine bessere Ressourceneffizienz ermöglicht und gleichzeitig bei jedem Durchlauf dieselbe gewünschte Umgebung bereitstellt. Docker Compose ist ein Container-Orchestrierungs-Tool, das moderne App-Anforderungen vereinfacht. Sie können damit mehrere miteinander verbundene Container gleichzeitig ausführen. Mithilfe von Orchestrierungstools können Entwickler Container nicht manuell ausführen, sondern gleichzeitig steuern, skalieren und erweitern.

Die Vorteile der Verwendung von Nginx als Front-End-Webserver sind die Leistung, die Konfigurierbarkeit und die TLS-Beendigung, wodurch die App von der Ausführung dieser Aufgaben befreit wird. Das https://github.com/jwilder/nginx-proxy [+ nginx-proxy +] ist ein automatisiertes System für Docker-Container, das die Konfiguration von Nginx als Reverse-Proxy erheblich vereinfacht. Https://www.digitalocean.com/community/tutorials/an-einführung-zum-Verschlüsseln-der-Verschlüsselung] https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion [ add-on] kann dem + nginx-proxy + beigefügt werden, um die Generierung und Erneuerung von Zertifikaten für Proxy-Container zu automatisieren.

In diesem Lernprogramm stellen Sie eine Go-Beispielwebanwendung mit gorilla/mux als Anforderungsrouter und Nginx als Webserver in Docker-Containern bereit, die von Docker Compose orchestriert wurden. Sie werden "+ nginx-proxy +" mit dem Let’s Encrypt-Add-On als Reverse-Proxy verwenden. Am Ende dieses Lernprogramms haben Sie eine Go-Webanwendung bereitgestellt, auf die in Ihrer Domain über mehrere Routen zugegriffen werden kann, die Docker verwendet und mit Let’s Encrypt-Zertifikaten gesichert ist.

Voraussetzungen

Schritt 1 - Beispiel erstellen Go Web App

In diesem Schritt richten Sie Ihren Arbeitsbereich ein und erstellen eine einfache Go-Web-App, die Sie später in Containern zusammenfassen. Die Go-App verwendet den leistungsstarken Anforderungsrouter gorilla/mux, der aufgrund seiner Flexibilität und Geschwindigkeit ausgewählt wurde.

Beginnen Sie mit der Anmeldung als "+ sammy +":

ssh @

In diesem Tutorial speichern Sie alle Daten unter "+ ~ / go-docker". Führen Sie dazu den folgenden Befehl aus:

mkdir ~/go-docker

Navigiere dorthin:

cd ~/go-docker

Sie speichern Ihre Beispiel-Go-Webanwendung in einer Datei mit dem Namen "+ main.go +". Erstellen Sie es mit Ihrem Texteditor:

nano main.go

Fügen Sie die folgenden Zeilen hinzu:

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)
}

Sie importieren zuerst die Pakete "+ net / http " und " gorilla / mux +", die die HTTP-Serverfunktionalität und das Routing bereitstellen.

Das "+ gorilla / mux " - Paket implementiert einen einfacheren und leistungsfähigeren Anforderungsrouter und Dispatcher, während gleichzeitig die Schnittstellenkompatibilität mit dem Standardrouter erhalten bleibt. Hier instanziieren Sie einen neuen " mux " - Router und speichern ihn in der Variablen " r ". Dann definieren Sie drei Routen: " / ", " / hallo " und " / hallo / {name} ". Das erste (" / ") dient als Startseite und Sie fügen eine Nachricht für die Seite hinzu. Das zweite (` / hello `) gibt eine Begrüßung an den Besucher zurück. Für die dritte Route (` / hallo / {name} +`) geben Sie an, dass ein Name als Parameter verwendet und eine Begrüßungsnachricht mit dem eingegebenen Namen angezeigt werden soll.

Am Ende Ihrer Datei starten Sie den HTTP-Server mit "+ http.ListenAndServe " und weisen ihn an, den Port " 80 +" über den von Ihnen konfigurierten Router abzuhören.

Speichern und schließen Sie die Datei.

Bevor Sie Ihre Go-App ausführen können, müssen Sie sie zunächst kompilieren und zur Ausführung in einen Docker-Container packen. Go ist eine https://www.digitalocean.com/community/tutorials/how-to-write-your-first-program-in-go#step-2-%E2%80%94-running-a-go- program [kompilierte Sprache]. Bevor ein Programm ausgeführt werden kann, übersetzt der Compiler den Programmcode in ausführbaren Maschinencode.

Sie haben Ihren Arbeitsbereich eingerichtet und eine Beispiel-Go-Webanwendung erstellt. Als nächstes werden Sie "+ nginx-proxy +" mit einer automatisierten Let’s Encrypt-Zertifikatsbereitstellung bereitstellen.

Schritt 2 - Bereitstellen von nginx-proxy mit Let’s Encrypt

Es ist wichtig, dass Sie Ihre App mit HTTPS sichern. Zu diesem Zweck stellen Sie "+ nginx-proxy " über Docker Compose zusammen mit dem Zusatz "Let's Encrypt" (https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion[add-on) bereit. Dies sichert Docker-Container, die mit " nginx-proxy +" als Proxy fungieren, und sichert Ihre App über HTTPS, indem die Erstellung und Erneuerung von TLS-Zertifikaten automatisch erfolgt.

Sie speichern die Docker Compose-Konfiguration für "+ nginx-proxy " in einer Datei mit dem Namen "+". Erstellen Sie es, indem Sie Folgendes ausführen:

nano

Fügen Sie der Datei die folgenden Zeilen hinzu:

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"

Hier definieren Sie zwei Container: einen für "+ nginx-proxy " und einen für das Let's Encrypt-Add-On (" letsencrypt-nginx-proxy-companion "). Für den Proxy geben Sie das Image ` jwilder / nginx-proxy +` an, machen HTTP- und HTTPS-Ports verfügbar und ordnen sie zu und definieren schließlich Volumes, auf die der Container für persistente Nginx-bezogene Daten zugreifen kann.

Im zweiten Block benennen Sie das Image für die Let’s Encrypt-Zusatzkonfiguration. Anschließend konfigurieren Sie den Zugriff auf den Docker-Socket, indem Sie ein Volume definieren und anschließend die vorhandenen Volumes aus dem Proxy-Container übernehmen. Bei beiden Containern ist die Eigenschaft "+ restart " auf " always +" gesetzt, wodurch Docker angewiesen wird, sie immer auf dem neuesten Stand zu halten (im Falle eines Absturzes oder eines Systemneustarts).

Speichern und schließen Sie die Datei.

Stellen Sie den + nginx-proxy + bereit, indem Sie Folgendes ausführen:

docker-compose -f  up -d

Docker Compose akzeptiert eine benutzerdefinierte benannte Datei über das Flag "+ -f ". Der Befehl " up " führt die Container aus, und das Flag " -d +" im getrennten Modus weist sie an, die Container im Hintergrund auszuführen.

Ihre endgültige Ausgabe sieht folgendermaßen aus:

OutputCreating 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

Sie haben "+ nginx-proxy +" und seinen Begleiter "Let’s Encrypt" mit Docker Compose bereitgestellt. Als Nächstes erstellen Sie eine Docker-Datei für Ihre Go-Webanwendung.

Schritt 3 - Andocken der Go Web App

In diesem Abschnitt erstellen Sie eine Docker-Datei mit Anweisungen, wie Docker ein unveränderliches Image für Ihre Go-Web-App erstellt. Docker erstellt anhand der Anweisungen in der Docker-Datei ein unveränderliches App-Image, das einem Snapshot des Containers ähnelt. Die Unveränderlichkeit des Images garantiert bei jeder Ausführung eines Containers basierend auf dem jeweiligen Image die gleiche Umgebung.

Erstellen Sie das + Dockerfile + mit Ihrem Texteditor:

nano Dockerfile

Fügen Sie die folgenden Zeilen hinzu:

Dockerfile

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

Dieses Dockerfile besteht aus zwei Phasen. In der ersten Stufe wird die Basis "+ golang: alpine +" verwendet, die das vorinstallierte Go für Alpine Linux enthält.

Anschließend installieren Sie "+ gcc", "+ g +", " make" und "+ git " als die erforderlichen Kompilierungswerkzeuge für Ihre Go-App. Sie legen das Arbeitsverzeichnis auf " / go / src / app " fest, das sich unter der Standardeinstellung "https://www.digitalocean.com/community/tutorials/understanding-the-gopath[GOPATH" befindet. Sie kopieren auch den Inhalt des aktuellen Verzeichnisses in den Container. Die erste Phase endet mit dem rekursiven Abrufen der verwendeten Pakete aus dem Code und dem Kompilieren der Datei " main.go " zur Freigabe ohne Symbol- und Debug-Informationen (durch Übergabe von " -ldflags =" - s -w "+"). Wenn Sie ein Go-Programm kompilieren, wird ein separater Teil der Binärdatei beibehalten, der für das Debuggen verwendet wird. Diese zusätzlichen Informationen belegen jedoch Speicher und müssen bei der Bereitstellung in einer Produktionsumgebung nicht beibehalten werden.

Die zweite Stufe basiert auf + alpine: 3.9 + (Alpine Linux 3.9). Es installiert vertrauenswürdige CA-Zertifikate, kopiert die kompilierten App-Binärdateien von der ersten Stufe in das aktuelle Image, macht den Port "+ 80 +" verfügbar und legt die App-Binärdatei als Image-Einstiegspunkt fest.

Speichern und schließen Sie die Datei.

Sie haben eine Docker-Datei für Ihre Go-App erstellt, mit der die Pakete abgerufen, zur Freigabe kompiliert und bei der Containererstellung ausgeführt werden. Im nächsten Schritt erstellen Sie die Docker Compose + yaml + -Datei und testen die App, indem Sie sie in Docker ausführen.

Schritt 4 - Erstellen und Ausführen der Docker Compose-Datei

Jetzt erstellen Sie die Docker Compose-Konfigurationsdatei und schreiben die erforderliche Konfiguration, um das im vorherigen Schritt erstellte Docker-Image auszuführen. Anschließend führen Sie es aus und prüfen, ob es ordnungsgemäß funktioniert. Im Allgemeinen werden in der Docker Compose-Konfigurationsdatei die Container, ihre Einstellungen, Netzwerke und Volumes angegeben, die für die App erforderlich sind. Sie können auch festlegen, dass diese Elemente gleichzeitig gestartet und gestoppt werden.

Sie speichern die Docker Compose-Konfiguration für die Go-Webanwendung in einer Datei mit dem Namen "++". Erstellen Sie es, indem Sie Folgendes ausführen:

nano

Fügen Sie dieser Datei die folgenden Zeilen hinzu:

go-app-compose.yaml

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

Denken Sie daran, "++" beide Male durch Ihren Domainnamen zu ersetzen. Speichern und schließen Sie die Datei.

Diese Docker Compose-Konfiguration enthält einen Container ("+ to-Web-App"), der Ihre Go-Web-App sein wird. Es erstellt die App mithilfe der Docker-Datei, die Sie im vorherigen Schritt erstellt haben, und verwendet das aktuelle Verzeichnis, das den Quellcode enthält, als Kontext für die Erstellung. Außerdem werden zwei Umgebungsvariablen gesetzt: "+ VIRTUAL_HOST " und " LETSENCRYPT_HOST ". ` nginx-proxy` verwendet` + VIRTUAL HOST`, um zu wissen, von welcher Domain die Anfragen angenommen werden sollen. "+ LETSENCRYPT_HOST " gibt den Domänennamen zum Generieren von TLS-Zertifikaten an und muss mit " VIRTUAL_HOST +" identisch sein, es sei denn, Sie geben eine Wildcard-Domäne an.

Jetzt können Sie Ihre Go-Webanwendung über Docker Compose mit dem folgenden Befehl im Hintergrund ausführen:

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

Ihre endgültige Ausgabe sieht folgendermaßen aus:

OutputCreating 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

Wenn Sie die Ausgabe überprüfen, die nach dem Ausführen des Befehls angezeigt wird, protokolliert Docker jeden Schritt des Erstellens des App-Images entsprechend der Konfiguration in Ihrer Docker-Datei.

Sie können jetzt zu "+ https: /// " navigieren, um Ihre Homepage anzuzeigen. Unter der Privatadresse Ihrer Web-App wird die Seite als Ergebnis der von Ihnen im ersten Schritt festgelegten " / +" -Route angezeigt.

image: https://assets.digitalocean.com/articles/godockernginx/step4a.png [Dies ist die Homepage. Versuchen Sie / Hallo und / Hallo / Sammy]

Navigieren Sie nun zu "+ https: /// hallo ". Sie sehen die Nachricht, die Sie in Ihrem Code für die Route " / hallo +" aus Schritt 1 definiert haben.

Versuchen Sie abschließend, einen Namen an die Adresse Ihrer Webanwendung anzuhängen, um die andere Route zu testen, z. B .: "+ https: /// hallo / Sammy +".

Sie haben die Docker Compose-Datei erstellt und die Konfiguration für die Ausführung Ihrer Go-App in einem Container geschrieben. Abschließend haben Sie zu Ihrer Domain navigiert, um zu überprüfen, ob das Routersetup "+ gorilla / mux +" Anforderungen an Ihre Dockerized Go-Webanwendung korrekt verarbeitet.

Fazit

Sie haben Ihre Go-Web-App jetzt erfolgreich mit Docker und Nginx unter Ubuntu 18.04 bereitgestellt. Mit Docker ist das Verwalten von Anwendungen kein Problem mehr, da die Umgebung, in der die App ausgeführt wird, bei jeder Ausführung garantiert dieselbe ist. Das Paket gorilla/mux verfügt über eine hervorragende Dokumentation und bietet komplexere Funktionen wie das Benennen von Routen und das Bereitstellen statischer Dateien. Weitere Informationen über das Go HTTP-Servermodul, beispielsweise zum Definieren benutzerdefinierter Zeitlimits, finden Sie unter official docs.