Cały moduł składał się z osobnych narzędzi: obraz, Compose, pipeline, sekrety, metryki, tracing, plan infrastruktury. Teraz zbierzemy je w jedną konfigurację - i przy okazji przypomnimy sobie, dlaczego każda decyzja wygląda tak, a nie inaczej. Bo to właśnie te uzasadnienia odróżniają konfigurację skopiowaną od zrozumianej.
1FROM node:20-alpine AS builder
2WORKDIR /app
3COPY package.json yarn.lock ./
4RUN yarn install --frozen-lockfile
5COPY . .
6RUN yarn build
7
8FROM node:20-alpine AS production
9WORKDIR /app
10RUN addgroup -g 1001 -S nodejs && adduser -S nestjs -u 1001
11COPY /app/dist ./dist
12COPY /app/node_modules ./node_modules
13USER nestjs
14EXPOSE 4000
15HEALTHCHECK \
16 CMD curl -f http://localhost:4000/health || exit 1
17CMD ["node", "dist/main"]Trzy decyzje w tym pliku warto umieć uzasadnić.
przenosi wynik z pierwszego etapu do drugiego. Kolejność członów jest stała: COPY --from=builder
, COPY
, --from=builder
(skąd), /app/dist
(dokąd). Dzięki temu w obrazie produkcyjnym nie ma kompilatora, źródeł ani zależności deweloperskich - zostaje sam wynik../dist
- użytkownika bez uprawnień root tworzymy, aby ograniczyć potencjalne szkody w przypadku włamania. Nie po to, żeby kontener startował szybciej, żeby obraz był mniejszy ani żeby umożliwić wielowątkowość. Proces działający jako root wewnątrz kontenera, po wyrwaniu się z izolacji, jest rootem także na hoście.USER nestjs
mówi Dockerowi, jak sprawdzić, czy aplikacja żyje naprawdę, a nie tylko czy proces istnieje. Kolejność: HEALTHCHECK
, healthcheck:
, test: curl -f http://localhost:4000/health
, interval: 30s
.retries: 3
W pliku Compose sprawdź dwie rzeczy, które najczęściej się myli.
Kontener
łączy się z bazą przez nazwę serwisu: api
- nie przez adres IP kontenera, nie przez mongodb:27017
localhost:27017 i nie przez zewnętrzny DNS. localhost wewnątrz kontenera to ten sam kontener, więc wskazywałby na API, nie na bazę.Flaga
w -v
usuwa wolumeny wraz z danymi. Nie włącza trybu szczegółowych logów, nie waliduje pliku i nie wypisuje wersji. To polecenie kasuje bazę - używaj go świadomie.docker compose down -v
Pełna droga zmiany na produkcję ma cztery etapy:
Czwarty etap bywa pomijany, a jest tym, który odróżnia „wdrożone" od „działa". Smoke tests to garść sprawdzeń najważniejszych ścieżek zaraz po wdrożeniu - czy strona się otwiera, czy logowanie przechodzi, czy zdrowie odpowiada. Pipeline mógł przejść na zielono, a aplikacja i tak nie wstać, bo zabrakło zmiennej środowiskowej, której na CI nikt nie potrzebował.
Gdy obraz jest gotowy, klaster przyjmuje opis zasobów z pliku:
1kubectl apply -f deployment.yamlKolejność członów:
, kubectl
, apply
, -f
. Flaga deployment.yaml
-f wskazuje plik z opisem; apply doprowadza klaster do stanu w nim zapisanego - tworzy, czego brakuje, i zmienia, co się różni.Skalowanie to osobne polecenie:
1kubectl scale deployment roman-api --replicas=5Tu kolejność brzmi:
, kubectl scale
, deployment roman-api
. Pięć replik znaczy pięć równoległych kopii aplikacji, między które klaster rozdzieli ruch.--replicas=5
Ostatnia rzecz z warstwy infrastruktury. Moduły w Terraform to reużywalne bloki infrastruktury, które można parametryzować - nie pluginy do komunikacji z chmurą (tym są providery), nie testy jednostkowe i nie pliki logów.
Sens jest ten sam co przy funkcji w kodzie: opisujesz raz „serwer aplikacyjny z bazą i siecią", a potem wywołujesz to trzy razy dla środowiska testowego, przedprodukcyjnego i produkcyjnego, zmieniając tylko parametry.
Zbierz komplet i sprawdź każdy punkt:
HEALTHCHECK,depends_on z service_healthy,push i pull_request, joby w kolejności lint → build → test → docker, sekrety w ustawieniach repozytorium,.env tylko lokalnie,/metrics, metryki RED, tracing z span.end() w finally,.tf, stan w backendzie zdalnym, nie w Gicie.Kampania gotowa do wymarszu:
COPY --from=builder przenosi wynik budowania: COPY, --from=builder, źródło, cel,HEALTHCHECK w kolejności: healthcheck:, test:, interval:, retries:,mongodb:27017), nie przez IP ani localhost,docker compose down -v usuwa wolumeny wraz z danymi,kubectl apply -f deployment.yaml wprowadza opis do klastra,kubectl scale deployment nazwa --replicas=5 zmienia liczbę kopii,To ostatnia lekcja modułu. Umiesz teraz zbudować obraz, opisać środowisko, przepuścić zmianę przez pipeline, ukryć sekrety, zobaczyć, co dzieje się na produkcji, i odtworzyć całą infrastrukturę z pliku. A na razie zapamiętaj: każdy element tej konfiguracji ma uzasadnienie - i to jego znajomość, a nie sam plik, przenosi się na następny projekt.