Како да распоредите 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
. Извршете ја следнава команда за да ја креирате оваа папка:
- mkdir ~/go-docker
Одете до него:
- cd ~/go-docker
Ќе ја зачувате вашата примерна веб-апликација Go во датотека со име main.go
. Направете го користејќи го вашиот уредувач на текст:
- 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
. Создадете го со извршување:
- 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
со извршување:
- 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
со вашиот уредувач на текст:
- 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
. Создадете го со извршување:
- 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:
- docker compose -f go-app-compose.yaml up -d
Ваквиот излез ќе се отпечати (овој излез е скратен заради читливост):
OutputCreating 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, одржувањето на апликациите не одзема толку време затоа што околината во која се извршува апликацијата е загарантирана да биде иста секогаш кога ќе се стартува. Официјалните документи.