Go dla początkujących - Część 16: Wdrażanie i konteneryzacja
Mateusz Kędziora

Go na Produkcji: Od Kodu do Działającej Aplikacji w Dockerze i Kubernetes
Witaj! Zaczynasz swoją przygodę z Go i chcesz dowiedzieć się, jak przenieść swój kod z komputera na działający serwer? Świetnie trafiłeś! Ten artykuł to kompleksowy przewodnik, który pokaże Ci, jak wdrożyć aplikację Go do środowiska produkcyjnego, wykorzystując narzędzia takie jak Docker i Kubernetes.
Go: Krótki Przegląd dla Początkujących
Jeśli jesteś zupełnie nowy w Go, spójrzmy na podstawowy przykład i wyjaśnimy, co się dzieje.
package main
import "fmt"
func main() {
message := "Witaj, świecie!"
fmt.Println(message)
}
Co robi ten kod?
package main
: Deklaruje, że ten plik jest głównym punktem wejścia aplikacji.import "fmt"
: Importuje pakietfmt
, który zawiera funkcje do formatowania i wypisywania tekstu.func main() {}
: Definiuje funkcjęmain
, która jest wykonywana po uruchomieniu programu.message := "Witaj, świecie!"
: Deklaruje zmiennąmessage
typu string i przypisuje jej wartość “Witaj, świecie!”.fmt.Println(message)
: Wywołuje funkcjęPrintln
z pakietufmt
, aby wypisać wartość zmiennejmessage
na konsoli.
To bardzo prosty przykład, ale pokazuje podstawową strukturę programu w Go. W kolejnych sekcjach będziemy używać bardziej złożonych przykładów, ale zawsze będziemy wyjaśniać każdy krok.
Docker: Konteneryzacja w Pigułce
Czym jest Docker?
Docker to platforma do konteneryzacji. Wyobraź sobie, że masz pudełko (kontener), w którym umieszczasz wszystko, czego potrzebuje Twoja aplikacja do działania: kod, biblioteki, zależności, konfigurację. Ten kontener jest izolowany od reszty systemu, co oznacza, że możesz go uruchomić na dowolnym serwerze, który ma zainstalowanego Dockera, a aplikacja będzie działać tak samo.
Po co używać Dockera?
- Spójność środowiska: Aplikacja działa tak samo na Twoim komputerze, na serwerze testowym i na serwerze produkcyjnym.
- Izolacja: Aplikacje są izolowane od siebie, co zwiększa bezpieczeństwo i stabilność.
- Skalowalność: Łatwo uruchomić wiele kopii aplikacji w kontenerach.
- Reprodukowalność: Definicja kontenera jest zawarta w pliku
Dockerfile
, dzięki czemu łatwo odtworzyć środowisko.
Tworzenie obrazu Docker dla aplikacji Go
Załóżmy, że masz prostą aplikację Go:
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
hostname, _ := os.Hostname()
fmt.Fprintf(w, "Witaj ze świata Go! Jestem uruchomiony na: %s\n", hostname)
})
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
fmt.Println("Serwer słucha na porcie: ", port)
http.ListenAndServe(":"+port, nil)
}
Opis kodu:
package main
: Deklaruje, że ten plik jest głównym punktem wejścia aplikacji.import (...)
: Importuje pakietyfmt
,net/http
ios
.fmt
: Do formatowania tekstu.net/http
: Do tworzenia serwera HTTP.os
: Do odczytywania zmiennych środowiskowych i pobierania nazwy hosta.
func main() {}
: Definiuje funkcjęmain
, która jest wykonywana po uruchomieniu programu.http.HandleFunc("/", ...)
: Rejestruje funkcję obsługującą żądania HTTP na ścieżce ”/”.hostname, _ := os.Hostname()
: Pobiera nazwę hosta, na którym działa aplikacja.fmt.Fprintf(w, ...)
: Wypisuje wiadomość na stronie internetowej, zawierającą nazwę hosta.
port := os.Getenv("PORT")
: Pobiera wartość zmiennej środowiskowej “PORT”. Jeśli zmienna nie jest ustawiona, ustawia domyślny port na “8080”.http.ListenAndServe(":"+port, nil)
: Uruchamia serwer HTTP na określonym porcie.
Teraz stwórzmy plik Dockerfile
:
# Użyj oficjalnego obrazu Go jako podstawy
FROM golang:1.24-alpine AS builder
# Ustaw katalog roboczy wewnątrz kontenera
WORKDIR /app
# Skopiuj pliki Go do kontenera
COPY . .
# Pobierz zależności
RUN go mod download
# Zbuduj aplikację
RUN go build -o main .
# Stwórz nowy, mniejszy obraz bazujący na Alpine Linux
FROM alpine:latest
# Skopiuj zbudowany plik wykonywalny z etapu budowy
COPY --from=builder /app/main /app/main
# Ustaw katalog roboczy
WORKDIR /app
# Ustaw port, na którym nasza aplikacja będzie nasłuchiwać
EXPOSE 8080
# Uruchom aplikację
CMD ["/app/main"]
Co robi ten plik Dockerfile?
FROM golang:1.24-alpine AS builder
: Bazuje na obraziegolang:1.24-alpine
, który zawiera środowisko Go. Używamy aliasubuilder
, aby później odwołać się do tego etapu. Obraz Alpine jest lekki, co pomoże nam zmniejszyć rozmiar obrazu wynikowego.WORKDIR /app
: Ustawia katalog/app
jako katalog roboczy wewnątrz kontenera.COPY . .
: Kopiuje wszystkie pliki z bieżącego katalogu (gdzie znajduje sięDockerfile
) do katalogu/app
w kontenerze.RUN go mod download
: Pobiera zależności projektu Go (zdefiniowane wgo.mod
).RUN go build -o main .
: Kompiluje kod Go do pliku wykonywalnego o nazwiemain
.FROM alpine:latest
: Bazuje na obraziealpine:latest
, który jest bardzo małym obrazem Linuxa.COPY --from=builder /app/main /app/main
: Kopiuje skompilowany plikmain
z etapubuilder
do katalogu/app
w nowym obrazie.WORKDIR /app
: Ustawia katalog/app
jako katalog roboczy.EXPOSE 8080
: Informuje, że aplikacja nasłuchuje na porcie 8080.CMD ["/app/main"]
: Uruchamia aplikację po uruchomieniu kontenera.
Budowanie obrazu Docker
Otwórz terminal w katalogu, gdzie masz plik Dockerfile
i uruchom:
docker build -t go-app .
Co robi to polecenie?
docker build
: Polecenie budujące obraz Dockera.-t go-app
: Nadaje obrazowi nazwęgo-app
.- .: Określa, że plik
Dockerfile
znajduje się w bieżącym katalogu.
Po zbudowaniu obrazu, możesz go uruchomić:
docker run -p 8080:8080 go-app
Co robi to polecenie?
docker run
: Polecenie uruchamiające kontener z obrazu.-p 8080:8080
: Przekierowuje port 8080 z komputera na port 8080 w kontenerze.go-app
: Nazwa obrazu, z którego ma być uruchomiony kontener.
Otwórz przeglądarkę i wpisz http://localhost:8080
. Powinieneś zobaczyć “Witaj ze świata Go!”.
Kubernetes: Orkestracja Kontenerów
Czym jest Kubernetes?
Kubernetes (często skracane do K8s) to system do orkiestracji kontenerów. Wyobraź sobie, że masz wiele kontenerów Docker, które tworzą Twoją aplikację. Kubernetes pomaga Ci nimi zarządzać: uruchamiać, skalować, aktualizować, monitorować i automatycznie naprawiać w przypadku awarii.
Dlaczego używać Kubernetesa?
- Automatyzacja: Kubernetes automatyzuje wiele zadań związanych z wdrażaniem i zarządzaniem aplikacjami w kontenerach.
- Skalowalność: Łatwo zwiększyć lub zmniejszyć liczbę działających kontenerów w zależności od obciążenia.
- Samonaprawa: Kubernetes automatycznie restartuje kontenery, które uległy awarii.
- Aktualizacje: Możesz aktualizować aplikacje bez przestojów.
- Orkiestracja: Kubernetes zarządza siecią, storage i konfiguracją aplikacji.
Podstawowe Koncepcje Kubernetesa
- Pod: Najmniejsza jednostka w Kubernetes. Może zawierać jeden lub więcej kontenerów. Kontenery w jednym Podzie współdzielą zasoby, takie jak sieć i storage.
- Deployment: Definicja, jak powinna być wdrażana aplikacja. Określa, ile kopii Podów ma być uruchomionych i jak powinny być aktualizowane.
- Service: Udostępnia aplikację na zewnątrz klastra Kubernetes. Działa jako proxy, kierując ruch do Podów.
- Namespace: Wirtualna przestrzeń nazw, która pozwala na logiczne oddzielenie zasobów w klastrze.
- Ingress: Zarządza dostępem zewnętrznym do usług w klastrze, zwykle poprzez HTTP/HTTPS.
- ConfigMap: Przechowuje dane konfiguracyjne dla aplikacji.
- Secret: Przechowuje poufne dane, takie jak hasła i klucze API.
Konfigurowanie Deploymentu i Serwisu dla aplikacji Go
Załóżmy, że mamy już zbudowany obraz Docker go-app
. Teraz stwórzmy pliki konfiguracyjne dla Kubernetesa.
Deployment (deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-app-deployment
labels:
app: go-app
spec:
replicas: 3 # Uruchom 3 kopie aplikacji
selector:
matchLabels:
app: go-app
template:
metadata:
labels:
app: go-app
spec:
containers:
- name: go-app
image: go-app # Nazwa Twojego obrazu Docker
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
Opis pliku Deployment:
apiVersion: apps/v1
: Określa wersję API dla Deploymentu.kind: Deployment
: Określa, że to jest definicja Deploymentu.metadata:
: Zawiera metadane o Deploymentu.name: go-app-deployment
: Nazwa Deploymentu.labels:
: Etykiety, które można użyć do identyfikacji Deploymentu.
spec:
: Określa pożądaną konfigurację Deploymentu.replicas: 3
: Określa, że chcemy uruchomić 3 repliki aplikacji.selector:
: Określa, które Pody Deployment ma zarządzać.matchLabels:
: Wybiera Pody z etykietąapp: go-app
.
template:
: Określa szablon dla Podów, które mają być utworzone.metadata:
: Zawiera metadane o Podzie.labels:
: Etykiety, które można użyć do identyfikacji Poda.
spec:
: Określa konfigurację Poda.containers:
: Lista kontenerów, które mają być uruchomione w Podzie.name: go-app
: Nazwa kontenera.image: go-app
: Nazwa obrazu Docker, który ma być użyty do utworzenia kontenera.ports:
: Lista portów, na których kontener nasłuchuje.containerPort: 8080
: Port, na którym kontener nasłuchuje.
env
: Zmienne środowiskowe dla kontenera.name: PORT
: Nazwa zmiennej środowiskowejvalue: "8080"
: Wartość zmiennej środowiskowej
Service (service.yaml):
apiVersion: v1
kind: Service
metadata:
name: go-app-service
spec:
selector:
app: go-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
Opis pliku Service:
apiVersion: v1
: Określa wersję API dla Serwisu.kind: Service
: Określa, że to jest definicja Serwisu.metadata:
: Zawiera metadane o Serwisie.name: go-app-service
: Nazwa Serwisu.
spec:
: Określa pożądaną konfigurację Serwisu.selector:
: Określa, które Pody Serwis ma kierować ruch do.app: go-app
: Wybiera Pody z etykietąapp: go-app
.
ports:
: Lista portów, na których Serwis nasłuchuje.protocol: TCP
: Protokół, którego Serwis używa.port: 80
: Port, na którym Serwis nasłuchuje z zewnątrz.targetPort: 8080
: Port, na którym Pody nasłuchują wewnątrz klastra.
type: LoadBalancer
: Typ Serwisu.LoadBalancer
udostępnia Serwis na zewnątrz klastra, tworząc zewnętrzny load balancer (jeśli jest dostępne w Twoim środowisku, np. w chmurze). W środowisku lokalnym (np. minikube) możesz użyćNodePort
zamiastLoadBalancer
.
Wdrażanie aplikacji na Kubernetes
Upewnij się, że masz dostęp do klastra Kubernetes (np. minikube, kind lub klaster w chmurze).
Uruchom następujące polecenia, aby wdrożyć aplikację:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Co robią te polecenia?
kubectl apply -f deployment.yaml
: Wdraża Deployment z plikudeployment.yaml
.kubectl apply -f service.yaml
: Wdraża Serwis z plikuservice.yaml
.
Sprawdź, czy aplikacja działa:
kubectl get deployments
kubectl get services
kubectl get pods
Co robią te polecenia?
kubectl get deployments
: Wyświetla listę Deploymentów.kubectl get services
: Wyświetla listę Serwisów.kubectl get pods
: Wyświetla listę Podów.
Jeśli używasz LoadBalancer
, sprawdź adres zewnętrzny Serwisu i otwórz go w przeglądarce. Jeśli używasz NodePort
, znajdź port, na którym Serwis jest dostępny na każdym węźle klastra i otwórz go w przeglądarce.
Praca Domowa
- Zmodyfikuj aplikację Go: Dodaj możliwość odczytywania zmiennej środowiskowej
MESSAGE
i wyświetlania jej na stronie internetowej. Jeśli zmienna nie jest ustawiona, wyświetl domyślny komunikat. - Zaktualizuj Dockerfile: Dodaj instrukcję, która ustawia zmienną środowiskową
MESSAGE
podczas budowania obrazu. - Zaktualizuj Deployment: Dodaj możliwość przekazywania zmiennej środowiskowej
MESSAGE
do kontenera za pomocą konfiguracji Deploymentu. - Wdróż aplikację: Zbuduj nowy obraz Docker, wdróż go na Kubernetes i sprawdź, czy zmienna środowiskowa
MESSAGE
jest poprawnie wyświetlana.
Podsumowanie i Co Dalej?
Gratulacje! Właśnie przeszliśmy razem przez proces wdrażania aplikacji Go do produkcji. Poznaliśmy podstawy Dockera i Kubernetesa, stworzyliśmy obraz Dockera dla naszej aplikacji i wdrożyliśmy ją na Kubernetes.
To, co dzisiaj zrobiliśmy, to tylko wierzchołek góry lodowej. W następnych wpisach przyjrzymy się bliżej konfiguracji aplikacji, monitoringowi, skalowaniu, zarządzaniu danymi i wiele innych.
Zachęcam Cię do samodzielnego eksperymentowania, czytania dokumentacji Dockera i Kubernetesa oraz oczywiście śledzenia naszego bloga. Im więcej ćwiczysz, tym lepiej zrozumiesz te technologie i tym łatwiej będzie Ci wdrażać swoje aplikacje w realnym świecie.
Przydatne linki
- Oficjalna dokumentacja Go: https://go.dev/
- Go by Example: https://gobyexample.com/
- Oficjalna dokumentacja Dockera: https://docs.docker.com/
- Docker Get Started: https://docs.docker.com/get-started/
- Oficjalna dokumentacja Kubernetes: https://kubernetes.io/
- Kubernetes Tutorials: https://kubernetes.io/docs/tutorials/
- Minikube: https://minikube.sigs.k8s.io/docs/
Do następnego razu!
Polecane artykuły
Docker vs Kubernetes: Który dla Ciebie w 2025?
Docker i Kubernetes objaśnione! Która technologia lepsza dla początkujących w 2025? Porównanie, przykłady i przyszłość.
Mateusz Kędziora
DevOps: Automatyzacja zadań sysadmina dla programistów
Zautomatyzuj pracę sysadmina w środowisku DevOps! Praktyczne przykłady, skrypty, Ansible, Terraform, Prometheus i Grafana.
Mateusz Kędziora
Automatyzacja Linux/macOS z Bash: Praktyczny Przewodnik
Zacznij automatyzować system Linux/macOS z Bash! Dowiedz się, czym jest Bash, jak pisać skrypty i używać podstawowych komend.
Mateusz Kędziora