Comment déployer une application Web Go avec Docker et Nginx sur Ubuntu 18.04

L’auteur a sélectionné le Free and Open Source pour recevoir un don dans le cadre du Write for DOnations programme.

introduction

Docker est le logiciel de conteneurisation le plus utilisé actuellement. Il permet aux développeurs de conditionner facilement les applications avec leurs environnements, ce qui permet des cycles d’itération plus rapides et une meilleure efficacité des ressources, tout en fournissant le même environnement souhaité à chaque exécution. Docker Compose est un outil d’orchestration de conteneur qui facilite la configuration requise pour les applications modernes. Il vous permet d’exécuter plusieurs conteneurs interconnectés en même temps. Au lieu d’exécuter manuellement des conteneurs, les outils d’orchestration offrent aux développeurs la possibilité de contrôler, de mettre à l’échelle et d’étendre un conteneur simultanément.

L’utilisation de Nginx en tant que serveur Web frontal présente les avantages suivants: performances, configurabilité et résiliation TLS, ce qui permet à l’application de ne pas effectuer ces tâches. Le https://github.com/jwilder/nginx-proxy [+ nginx-proxy +] est un système automatisé pour les conteneurs Docker qui simplifie grandement le processus de configuration de Nginx pour servir de proxy inverse. Son cryptage Let https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion [ add-on] peut accompagner le + nginx-proxy + pour automatiser la génération et le renouvellement de certificats pour les conteneurs mandatés.

Dans ce didacticiel, vous allez déployer un exemple d’application Web Go avec gorilla/mux en tant que routeur de demande et Nginx en tant que serveur Web, tous à l’intérieur de conteneurs Docker, orchestrés par Docker Compose. Vous utiliserez + nginx-proxy + avec le module complémentaire Let Encrypt en tant que proxy inverse. À la fin de ce didacticiel, vous aurez déployé une application Web Go accessible sur votre domaine avec plusieurs itinéraires, à l’aide de Docker et sécurisée avec des certificats Let’s Encrypt.

Conditions préalables

Étape 1 - Création d’un exemple d’application Web

Au cours de cette étape, vous allez configurer votre espace de travail et créer une application Web Go simple, que vous allez ensuite conteneuriser. L’application Go utilisera le puissant routeur de requêtes gorilla/mux, choisi pour sa souplesse et sa rapidité.

Commencez par vous connecter en tant que + sammy +:

ssh @

Pour ce tutoriel, vous allez stocker toutes les données sous + ~ / go-docker. Exécutez la commande suivante pour cela:

mkdir ~/go-docker

Naviguez jusqu’à:

cd ~/go-docker

Vous allez stocker votre exemple d’application Web dans un fichier nommé + main.go +. Créez-le en utilisant votre éditeur de texte:

nano main.go

Ajoutez les lignes suivantes:

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

Commencez par importer les packages + net / http + 'et + gorilla / mux + `, qui fournissent les fonctionnalités et le routage du serveur HTTP.

Le package + gorilla / mux + implémente un routeur de demande et un répartiteur de requêtes plus simples et plus puissants, tout en maintenant la compatibilité d’interface avec le routeur standard. Ici, vous instanciez un nouveau routeur + mux + et le stockiez dans la variable + r +. Ensuite, vous définissez trois itinéraires: + / +, + / hello + et + / hello / {name} +. Le premier (+ / +) sert de page d’accueil et vous incluez un message pour la page. La seconde (+ / hello +) renvoie un message au visiteur. Pour la troisième route (+ / hello / {name} +), vous indiquez qu’elle doit prendre un nom en tant que paramètre et afficher un message d’accueil avec le nom inséré.

A la fin de votre fichier, vous démarrez le serveur HTTP avec + http.ListenAndServe + et lui demandez d’écouter sur le port + 80 +, à l’aide du routeur que vous avez configuré.

Enregistrez et fermez le fichier.

Avant d’exécuter votre application Go, vous devez d’abord la compiler et la compiler pour qu’elle soit exécutée dans un conteneur Docker. Go est un https://www.digitalocean.com/community/tutorials/how-to-write-your-first-program-in-go#step-2-%E2%80%94-running-a-go- programme [langage compilé], donc avant qu’un programme puisse s’exécuter, le compilateur traduit le code de programmation en code machine exécutable.

Vous avez configuré votre espace de travail et créé un exemple d’application Web Go. Ensuite, vous allez déployer + nginx-proxy + avec une fourniture de certificat automatique Let’s Encrypt.

Étape 2 - Déploiement de nginx-proxy avec Let’s Encrypt

Il est important de sécuriser votre application avec HTTPS. Pour ce faire, vous allez déployer + nginx-proxy + via Docker Compose, avec son encryptage Let’s Encrypt add-on. Cela sécurise les conteneurs Docker en utilisant un proxy avec + nginx-proxy +, et prend en charge la sécurisation de votre application via HTTPS en gérant automatiquement la création et le renouvellement du certificat TLS.

Vous allez stocker la configuration de Docker Compose pour + nginx-proxy + dans un fichier nommé ++. Créez-le en exécutant:

nano

Ajoutez les lignes suivantes au fichier:

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"

Vous définissez ici deux conteneurs: un pour + nginx-proxy + et un pour son complément Let’s Encrypt (+ letsencrypt-nginx-proxy-companion +). Pour le proxy, vous spécifiez l’image + jwilder / nginx-proxy +, vous exposez et mappez les ports HTTP et HTTPS, puis vous définissez les volumes qui seront accessibles au conteneur pour la persistance des données liées à Nginx.

Dans le deuxième bloc, vous nommez l’image de la configuration complémentaire Let’s Encrypt. Ensuite, vous configurez l’accès au socket de Docker en définissant un volume, puis les volumes existants du conteneur de proxy à hériter. La propriété + restart + est définie sur + always + pour les deux conteneurs, ce qui indique à Docker de toujours les conserver (en cas de blocage ou de redémarrage du système).

Enregistrez et fermez le fichier.

Déployez le + nginx-proxy + en lançant:

docker-compose -f  up -d

Docker Compose accepte un fichier nommé personnalisé via l’indicateur + -f +. La commande + up + exécute les conteneurs, et l’indicateur + -d +, en mode détaché, lui indique d’exécuter les conteneurs en arrière-plan.

Votre sortie finale ressemblera à ceci:

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

Vous avez déployé + nginx-proxy + et son compagnon Let’s Encrypt à l’aide de Docker Compose. Vous allez ensuite créer un fichier Dockerfile pour votre application Web Go.

Étape 3 - Dockérisation de l’application Web Go

Dans cette section, vous allez créer un fichier Docker contenant des instructions sur la manière dont Docker créera une image immuable pour votre application Web Go. Docker crée une image d’application immuable, semblable à un instantané du conteneur, à l’aide des instructions contenues dans le fichier Docker. L’immuabilité de l’image garantit le même environnement à chaque exécution d’un conteneur basé sur une image donnée.

Créez le + Dockerfile + avec votre éditeur de texte:

nano Dockerfile

Ajoutez les lignes suivantes:

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

Ce fichier docker a deux étapes. La première étape utilise la base + golang: alpine +, qui contient Go pré-installé sur Linux Linux.

Ensuite, vous installez + gcc,` + g + `,` + make` et ` git ` en tant qu'outils de compilation nécessaires pour votre application Go. Vous définissez le répertoire de travail sur ` / go / src / app `, qui se trouve sous le répertoire par défaut https://www.digitalocean.com/community/tutorials/understanding-the-gopath[GOPATH]. Vous copiez également le contenu du répertoire en cours dans le conteneur. La première étape se termine par l'extraction récursive des packages utilisés dans le code et la compilation du fichier ` main.go ` pour publication sans symbole ni information de débogage (en passant ` -ldflags =" - s -w "+`). Lorsque vous compilez un programme Go, il conserve une partie distincte du fichier binaire qui serait utilisé pour le débogage. Toutefois, cette information supplémentaire utilise la mémoire et n’est pas nécessaire à préserver lors du déploiement dans un environnement de production.

La deuxième étape se base sur + alpine: 3.9 + (Alpine Linux 3.9). Il installe des certificats d’autorité de certification sécurisés, copie les fichiers binaires de l’application compilés de la première étape vers l’image actuelle, expose le port `80+ + et définit le binaire de l’application comme point d’entrée de l’image.

Enregistrez et fermez le fichier.

Vous avez créé un fichier Dockerfile pour votre application Go qui va récupérer ses packages, le compiler pour publication et l’exécuter lors de la création du conteneur. Dans l’étape suivante, vous allez créer le fichier Docker Compose + yaml + et tester l’application en l’exécutant dans Docker.

Étape 4 - Création et exécution du fichier Docker Compose

Vous allez maintenant créer le fichier de configuration Docker Compose et écrire la configuration nécessaire à l’exécution de l’image Docker créée à l’étape précédente. Ensuite, vous allez l’exécuter et vérifier si cela fonctionne correctement. En général, le fichier de configuration de Docker Compose spécifie les conteneurs, leurs paramètres, les réseaux et les volumes requis par l’application. Vous pouvez également spécifier que ces éléments peuvent être démarrés et arrêtés simultanément.

Vous allez stocker la configuration Docker Compose pour l’application Web Aller dans un fichier nommé ++. Créez-le en exécutant:

nano

Ajoutez les lignes suivantes à ce fichier:

go-app-compose.yaml

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

N’oubliez pas de remplacer ++ les deux fois par votre nom de domaine. Enregistrez et fermez le fichier.

Cette configuration Docker Compose contient un conteneur (+ to-web-app), qui sera votre application Web Go. Il crée l’application à l’aide du fichier Docker que vous avez créé à l’étape précédente et prend le répertoire actuel, qui contient le code source, comme contexte de création. De plus, il définit deux variables d’environnement: + VIRTUAL_HOST + et + LETSENCRYPT_HOST +. + nginx-proxy utilise` + VIRTUAL HOST` pour savoir à partir de quel domaine accepter les demandes. + LETSENCRYPT_HOST + spécifie le nom de domaine pour la génération de certificats TLS et doit être identique à + ​​VIRTUAL_HOST +, sauf si vous spécifiez un domaine générique.

Vous allez maintenant exécuter votre application Web Go en arrière-plan via Docker Compose à l’aide de la commande suivante:

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

Votre sortie finale ressemblera à ceci:

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

Si vous examinez le résultat présenté après l’exécution de la commande, Docker enregistre chaque étape de la création de l’image de l’application en fonction de la configuration de votre fichier Docker.

Vous pouvez maintenant naviguer vers + https: /// + pour voir votre page d’accueil. À l’adresse personnelle de votre application Web, la page s’affiche à la suite de l’itinéraire + / + que vous avez défini lors de la première étape.

image: https: //assets.digitalocean.com/articles/godockernginx/step4a.png [Ceci est la page d’accueil. Essayez / bonjour et / bonjour / Sammy]

Maintenant, naviguez vers + https: /// hello +. Vous verrez le message que vous avez défini dans votre code pour la route + / hello + à partir de l’étape 1.

image: https: //assets.digitalocean.com/articles/godockernginx/step4b.png [Bonjour de Docker!]

Enfin, essayez d’ajouter un nom à l’adresse de votre application Web pour tester l’autre itinéraire, par exemple: + https: /// hello / Sammy +.

image: https: //assets.digitalocean.com/articles/godockernginx/step4c.png [Bonjour, Sammy!]

Vous avez créé le fichier Docker Compose et la configuration écrite pour exécuter votre application Go dans un conteneur. Pour terminer, vous avez accédé à votre domaine pour vérifier que la configuration du routeur + gorilla / mux + répond correctement aux demandes de votre application Web Dockerized Go.

Conclusion

Vous avez maintenant déployé avec succès votre application Web Go avec Docker et Nginx sur Ubuntu 18.04. Avec Docker, la maintenance des applications devient moins fastidieuse, car il est garanti que l’environnement dans lequel l’application est exécutée est le même à chaque exécution. Le package gorilla/mux dispose d’une excellente documentation et propose des fonctionnalités plus sophistiquées, telles que l’attribution de noms à des itinéraires et la gestion de fichiers statiques. Pour plus de contrôle sur le module de serveur HTTP Go, comme la définition de délais d’expiration personnalisés, visitez le site official docs.