Како да распоредите Go Web апликација со Docker и Nginx на Ubuntu 22.04


Авторот ја избра програмата Пишувај за донации.

Вовед

Docker Compose е алатка за оркестрација на контејнери што ги олеснува современите барања за апликации. Тоа ви овозможува да извршувате повеќе меѓусебно поврзани контејнери во исто време. Наместо рачно пуштање контејнери, алатките за оркестрација им даваат на програмерите можност истовремено да контролираат, размеруваат и продолжуваат контејнер.

Придобивките од користењето на Nginx како преден веб-сервер се во перформансите, конфигурабилноста и завршувањето на TLS, што ја ослободува апликацијата од завршување на овие задачи. Додатокот може да го придружува nginx-proxy за да го автоматизира генерирањето и обновувањето на сертификатите за прокси контејнери.

Во ова упатство, ќе распоредите примерна веб-апликација Go со горила/mux како рутер за барање и Nginx како веб-сервер, сето тоа во контејнерите на Docker кои се оркестрирани од Docker Compose. Ќе користите nginx-proxy со додатокот Let’s Encrypt како обратен прокси. На крајот од ова упатство, ќе имате распоредено веб-апликација Go достапна на вашиот домен со повеќе правци, користејќи Docker и обезбедена со Let’s Encrypt сертификати.

Предуслови

  • Сервер на Ubuntu 22.04 со права на root и секундарна, не-root сметка. Можете да го поставите ова следејќи го ова почетно упатство за поставување сервер. За ова упатство, корисникот кој не е root е sammy.
  • Docker се инсталира со следење на првите два чекори од Како да се инсталира Docker на Ubuntu 22.04.
  • Docker Compose се инсталира со следење на првиот чекор од Како да се инсталира Docker Compose на Ubuntu 22.04.
  • Целосно регистрирано име на домен. Ова упатство ќе го користи вашиот_домен насекаде. Можете да добиете еден бесплатно на Freenom или да користите регистратор на домени по ваш избор.
  • Запис за DNS \A со your_domain што покажува на јавната IP адреса на вашиот сервер. Можете да го следите овој вовед во DigitalOcean DNS за детали како да ги додадете.
  • Разбирање на Docker и неговата архитектура. За вовед во Docker, видете Докер екосистем: Вовед во заеднички компоненти.

Чекор 1 - Креирање на пример Go Web апликација

Во овој чекор, ќе го поставите вашиот работен простор и ќе создадете едноставна веб-апликација Go, која подоцна ќе ја ставите во контејнер. Апликацијата Go ќе го користи моќниот рутер за барање горила/mux, избран поради неговата флексибилност и брзина.

За ова упатство, ќе ги зачувате сите податоци под ~/go-docker. Извршете ја следнава команда за да ја креирате оваа папка:

  1. mkdir ~/go-docker

Одете до него:

  1. cd ~/go-docker

Ќе ја зачувате вашата примерна веб-апликација Go во датотека со име main.go. Направете го користејќи го вашиот уредувач на текст:

  1. nano 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)
}

Прво ги увезувате пакетите net/http и gorilla/mux, кои обезбедуваат функционалност и рутирање на серверот HTTP. Пакетот gorilla/mux имплементира помоќен рутер за барање и диспечер, додека ја одржува компатибилноста на интерфејсот со стандардниот рутер. Инстанцирате нов рутер mux и го складирате во променливата r.

Потоа, дефинирате три правци: /, /hello и /hello/{name}. Првата (/) служи како почетна страница и вие вклучувате порака за страницата. Вториот (/hello) враќа поздрав до посетителот. За третата рута (/hello/{name}), одредувате дека треба да земе име како параметар и да прикаже поздравна порака со внесеното име.

На крајот од вашата датотека, го стартувате серверот HTTP со http.ListenAndServe и му наложувате да слуша на портата 80, користејќи го рутерот што сте го конфигурирале.

Зачувајте ја и затворете ја датотеката.

Пред да ја стартувате апликацијата Go, треба да ја компајлирате и спакувате за извршување во контејнер Docker. Go е компајлиран јазик, па пред да може да работи програмата, компајлерот го преведува програмскиот код во извршна машинска шифра.

Го поставивте вашиот работен простор и создадовте пример за веб-апликација Go. Следно, ќе распоредите nginx-proxy со автоматизирана одредба за сертификат Let’s Encrypt.

Чекор 2 - Распоредување на nginx-прокси со Let’s Encrypt

Важно е да ја обезбедите вашата апликација со HTTPS. За да го постигнете ова, ќе распоредите nginx-proxy преку Docker Compose, заедно со неговиот додаток Let’s Encrypt. Ова поставување ги обезбедува контејнерите на Docker проксирано со помош на nginx-proxy и се грижи за обезбедување на вашата апликација преку HTTPS со автоматско управување со создавањето и обновувањето на сертификатот TLS.

Ќе ја складирате конфигурацијата Docker Compose за nginx-proxy во датотека со име nginx-proxy-compose.yaml. Создадете го со извршување:

  1. nano nginx-proxy-compose.yaml

Додадете ги следните редови во датотеката:

version: '3'

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"

Во оваа датотека, вие дефинирате два контејнери: еден за nginx-proxy и еден за неговиот додаток Let’s Encrypt (letsencrypt-nginx-proxy-companion). За прокси-серверот, ја одредувате сликата jwilder/nginx-proxy, ги изложувате и мапирате HTTP и HTTPS портите и дефинирате волумени што ќе бидат достапни до контејнерот за постојани податоци поврзани со Nginx.

Во вториот блок, ја именувате сликата за конфигурацијата на додатокот Let’s Encrypt. Потоа, го конфигурирате пристапот до приклучокот на Docker со дефинирање на волумен, а потоа постоечките волумени од контејнерот за прокси за наследување. И двата контејнери имаат својство рестартирај поставено на секогаш, што му наложува на Docker секогаш да ги одржува (во случај на пад или рестартирање на системот).

Зачувајте ја и затворете ја датотеката.

Распоредете го nginx-proxy со извршување:

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

Docker Compose прифаќа приспособена датотека со име преку знамето -f. Командата up ги извршува контејнерите, а знамето -d (одвоен режим) ѝ дава инструкции да ги извршува контејнерите во позадина.

Ќе добиете вака излез:

Output
[+] Running 21/21 ⠿ letsencrypt-nginx-proxy-companion Pulled 6.8s ⠿ df9b9388f04a Pull complete 3.1s ⠿ 6c6cfd4eaf5b Pull complete 3.9s ⠿ 870307501973 Pull complete 4.3s ⠿ e8ff3435d14f Pull complete 4.5s ⠿ 5b78ba945919 Pull complete 4.8s ⠿ 973b2ca26006 Pull complete 5.0s ⠿ nginx-proxy Pulled 8.1s ⠿ 42c077c10790 Pull complete 3.9s ⠿ 62c70f376f6a Pull complete 5.5s ⠿ 915cc9bd79c2 Pull complete 5.6s ⠿ 75a963e94de0 Pull complete 5.7s ⠿ 7b1fab684d70 Pull complete 5.7s ⠿ db24d06d5af4 Pull complete 5.8s ⠿ e917373dbecf Pull complete 5.9s ⠿ 11e2be9775e9 Pull complete 5.9s ⠿ 9996fa75bc02 Pull complete 6.1s ⠿ d37674efdf77 Pull complete 6.3s ⠿ a45d84576e75 Pull complete 6.3s ⠿ a13c1f42faf7 Pull complete 6.4s ⠿ 4f4fb700ef54 Pull complete 6.5s [+] Running 3/3 ⠿ Network go-docker_default Created 0.1s ⠿ Container go-docker-nginx-proxy-1 Started 0.5s ⠿ Container go-docker-letsencrypt-nginx-proxy-companion-1 Started 0.8s

Употребивте nginx-proxy и неговиот придружник Let’s Encrypt користејќи Docker Compose. Следно, ќе креирате Dockerfile за вашата веб-апликација Go.

Чекор 3 - Докеризирање на Go Web апликацијата

Во овој дел, ќе подготвите Dockerfile што содржи упатства за тоа како Docker ќе создаде непроменлива слика за вашата веб-апликација Go. Docker создава непроменлива слика на апликацијата, слична на слика од контејнерот, користејќи ги инструкциите што се наоѓаат во Dockerfile. Непроменливоста на сликата го гарантира истото опкружување секој пат кога се работи контејнер, врз основа на одредена слика.

Направете го Dockerfile со вашиот уредувач на текст:

  1. nano Dockerfile

Додадете ги следните линии:

FROM golang:alpine AS build
RUN apk --no-cache add gcc g++ make git
WORKDIR /go/src/app
COPY . .
RUN go mod init webserver
RUN go mod tidy
RUN GOOS=linux go build -ldflags="-s -w" -o ./bin/web-app ./main.go

FROM alpine:3.17
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

Оваа Dockerfile има две фази. Првата фаза ја користи базата golang:alpine, која содржи претходно инсталирано Go на Alpine Linux.

Потоа ги инсталирате gcc, g++, make и git како неопходни алатки за компилација за вашата апликација Go. Го поставивте работниот директориум на /go/src/app, што е под стандардниот GOPATH. Исто така, ја копирате содржината на тековниот директориум во контејнерот. Првата фаза завршува со рекурзивно преземање на користените пакети од кодот и компајлирање на датотеката main.go за објавување без симбол и информации за отстранување грешки (со додавање -ldflags=-s -w< /шифра>).

Забелешка: Кога компајлирате програма Go, таа задржува посебен дел од бинарната датотека што ќе се користи за дебагирање; сепак, оваа дополнителна информација користи меморија и не е неопходно да се зачува при распоредување во производствена средина.

Втората фаза се заснова на alpine:3.17 (Alpine Linux 3.17). Инсталира доверливи CA сертификати, ги копира компајлираните бинарни датотеки на апликацијата од првата фаза до тековната слика, ја изложува портата 80 и ја поставува бинарната апликација како влезна точка на сликата.

Зачувајте ја и затворете ја датотеката.

Создадовте Dockerfile за вашата апликација Go што ќе ги преземе нејзините пакети, ќе ја компајлира за објавување и ќе ја стартува при креирањето на контејнер. Во следниот чекор, ќе ја креирате датотеката Docker Compose yaml и ќе ја тестирате апликацијата со тоа што ќе ја извршите во Docker.

Чекор 4 - Креирање и извршување на датотеката за составување на Docker

Сега, ќе ја креирате конфигурациската датотека Docker Compose и ќе ја напишете потребната конфигурација за извршување на сликата на Docker што сте ја создале во претходниот чекор. Потоа, ќе го извршите и ќе проверите дали работи правилно. Општо земено, конфигурациската датотека Docker Compose ги специфицира контејнерите, поставките, мрежите и волумените што ги бара апликацијата. Можете исто така да наведете дека овие елементи започнуваат и запираат како еден.

Ќе ја складирате конфигурацијата Docker Compose за веб-апликацијата Go во датотека со име go-app-compose.yaml. Создадете го со извршување:

  1. nano go-app-compose.yaml

Додадете ги следните редови во оваа датотека:

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

Заменете го your_domain двата пати со името на вашиот домен. Зачувајте ја и затворете ја датотеката.

Оваа конфигурација на Docker Compose содржи еден контејнер (go-web-app), кој ќе биде вашата веб-апликација Go. Ја гради апликацијата користејќи ја Dockerfile што сте ја создале во претходниот чекор и го зема тековниот директориум, кој го содржи изворниот код, како контекст за градење. Понатаму, поставува две променливи на околината: VIRTUAL_HOST и LETSENCRYPT_HOST. nginx-proxy користи VIRTUAL_HOST за да знае од кој домен да ги прифати барањата. LETSENCRYPT_HOST го одредува името на доменот за генерирање на TLS сертификати и мора да биде исто како VIRTUAL_HOST, освен ако не наведете домен со џокер.

Сега стартувајте ја вашата веб-апликација Go во заднина преку Docker Compose:

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

Ваквиот излез ќе се отпечати (овој излез е скратен заради читливост):

Output
Creating network "go-docker_default" with the default driver Building go-web-app Step 1/13 : FROM golang:alpine AS build ---> b97a72b8e97d ... Successfully built 71e4b1ef2e25 Successfully tagged go-docker_go-web-app:latest ... [+] Running 1/1 ⠿ Container go-docker-go-web-app-1 Started

Ако го прегледате излезот претставен по извршувањето на командата, Docker го евидентира секој чекор од градењето на сликата на апликацијата според конфигурацијата во вашата Dockerfile.

Сега можете да отидете на https://your_domain/ за да пристапите до вашата почетна страница. На домашната адреса на вашата веб-апликација, можете да пристапите на страницата како резултат на рутата / што ја дефиниравте во првиот чекор.

Сега одете до https://your_domain/hello. Ќе се вчита пораката што ја дефиниравте во вашиот код за маршрутата /hello од чекор 1.

Конечно, додајте име на адресата на вашата веб-апликација за да ја тестирате другата рута, како: https://your_domain/hello/Sammy.

Забелешка: Ако примите грешка за неважечки TLS сертификати, почекајте неколку минути за додатокот Let’s Encrypt да ги обезбеди сертификатите. Ако сè уште добивате грешки по кратко време, проверете двапати што сте внеле според командите и конфигурацијата во овој чекор.

Ја создадовте датотеката Docker Compose и напишаната конфигурација за извршување на вашата апликација Go во контејнер. За да завршите, отидовте до вашиот домен за да проверите дали поставувањето на рутерот gorilla/mux правилно ги опслужува барањата до вашата веб-апликација Dockerized Go.

Заклучок

Сега успешно ја распоредивте вашата веб-апликација Go со Docker и Nginx на Ubuntu 22.04. Со Docker, одржувањето на апликациите не одзема толку време затоа што околината во која се извршува апликацијата е загарантирана да биде иста секогаш кога ќе се стартува. Официјалните документи.