Kurs NestJS · Moduł 9: Deployment i infrastruktura
PROJEKT: Pełne wdrożenie aplikacji NestJS do produkcji
W tej lekcji2
Legacie! Twoja aplikacja działa na laptopie, ale Konsul Caesar.js zadaje pytania, które padają przy każdym prawdziwym wdrożeniu: co się stanie, gdy serwer zgaśnie o trzeciej w nocy? Kto zauważy, że baza zwalnia? Skąd wiesz, że kopia z wczoraj da się odtworzyć? Konsul powierza Ci największe wyzwanie - kompletne wdrożenie rzymskiego legionu do produkcji. To prawdziwy test umiejętności, które zdobyłeś podczas naszej kampanii z NestJS.
Specyfikacja Projektu
Twoim zadaniem jest stworzenie kompletnego systemu deploymentu dla aplikacji Legionary Legion API. Każda część opiera się na lekcjach tego i poprzednich modułów, więc przed startem wróć do nich jak do map sztabowych. Podane godziny to orientacyjny czas pracy.
1. Infrastruktura (4-5 godzin)
- Konfiguracja Docker i Docker Compose
- Setup Kubernetes/Helm charts
- Konfiguracja CI/CD pipeline
- Monitoring i logging
Zacznij od obrazu zbudowanego w multi-stage build i pliku Compose, który stawia aplikację razem z MongoDB i Redisem. W Kubernetesie opisz repliki, strategię rolling update i sondy readiness oraz liveness. Pipeline ma uruchamiać testy, budować obraz i wdrażać go dopiero po zielonych testach.
2. Bezpieczeństwo (2-3 godziny)
- Implementacja SSL/TLS
- Security headers i rate limiting
- Secrets management
- Vulnerability scanning
HTTPS, nagłówki z Helmet i limity z throttlera już znasz. Sekrety trzymaj poza repozytorium i obrazem, a aplikacja niech odmawia startu, gdy któregoś brakuje. Skaner podatności, np. Trivy, dołącz do pipeline'u, żeby obraz z krytyczną luką nie trafił na produkcję.
3. Performance (2-3 godziny)
- Load balancing i auto-scaling
- Caching strategy
- Database optimization
- CDN setup
Zmierz, zanim zaczniesz optymalizować: wynik testu obciążeniowego przed zmianami i po nich to najlepszy dowód. Dobierz indeksy do najczęstszych zapytań, cache w Redisie z przemyślanym unieważnianiem i nagłówki cache dla CDN. Autoskalowanie dokłada repliki według metryk, np. CPU, więc aplikacja musi być bezstanowa: sesje i cache mieszkają w Redisie, nie w pamięci procesu.
4. Monitoring (2-3 godziny)
- Health checks
- Metrics collection
- Alerting system
- Log aggregation
Endpointy zdrowia rozdziel na liveness i readiness, metryki wystaw dla Prometheusa, a logi zapisuj w JSON-ie z identyfikatorem żądania. Alert ma budzić tylko wtedy, gdy trzeba coś zrobić - zbyt głośny alarm szybko przestaje być słyszany.
5. Backup & Recovery (1-2 godziny)
- Automated backups
- Disaster recovery plan
- Data integrity checks
Backup uruchamiaj automatycznie, ustal RTO i RPO, a potem przeprowadź jedno pełne odtworzenie na świeżym środowisku i zapisz, ile trwało.
Kryteria Oceny
- Kompletność - wszystkie komponenty działają razem
- Bezpieczeństwo - właściwe zabezpieczenia na każdej warstwie, od TLS po sekrety
- Wydajność - aplikacja wytrzymuje ruch produkcyjny, co potwierdza test obciążeniowy
- Monitoring - pełna obserwowalność: metryki, logi i alerty
- Dokumentacja - runbooki wdrożenia i odtwarzania
Mentor oceni projekt po repozytorium, więc README musi zawierać polecenia uruchomienia, opis architektury i wyniki testu odtworzenia. Polecam Ci pisać runbook równolegle z konfiguracją, a nie na końcu - to, czego nie zapiszesz od razu, o trzeciej w nocy będzie tylko domysłem.
Powodzenia, legacie! Twój legion liczy na Ciebie, a gotowy system wyślesz mentorowi na końcu modułu.
Kod do tej lekcji: deployment-project/docker-compose.yml
1# PROJEKT: Pelne Wdrozenie Aplikacji NestJS do Produkcji
2
3version: '3.8'
4
5services:
6 # === API NestJS ===
7 api:
8 build:
9 context: .
10 dockerfile: Dockerfile
11 container_name: roman-api
12 restart: unless-stopped
13 ports:
14 - "4000:4000"
15 environment:
16 NODE_ENV: production
17 PORT: 4000
18 MONGO_URI: mongodb://mongo:27017/roman_empire
19 REDIS_HOST: redis
20 REDIS_PORT: 6379
21 JWT_SECRET: ${JWT_SECRET}
22 ALLOWED_ORIGINS: https://roman-empire.com
23 depends_on:
24 mongo:
25 condition: service_healthy
26 redis:
27 condition: service_healthy
28 healthcheck:
29 test: ["CMD", "node", "-e",
30 "require('http').get('http://localhost:4000/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1) })"]
31 interval: 30s
32 timeout: 10s
33 retries: 3
34 start_period: 40s
35 networks:
36 - roman-network
37
38 # === MongoDB ===
39 mongo:
40 image: mongo:7
41 container_name: roman-mongodb
42 restart: unless-stopped
43 volumes:
44 - mongo-data:/data/db
45 - ./scripts/backup.sh:/scripts/backup.sh
46 environment:
47 MONGO_INITDB_DATABASE: roman_empire
48 healthcheck:
49 test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok"]
50 interval: 10s
51 timeout: 5s
52 retries: 5
53 networks:
54 - roman-network
55
56 # === Redis Cache ===
57 redis:
58 image: redis:7-alpine
59 container_name: roman-redis
60 restart: unless-stopped
61 command: redis-server --appendonly yes
62 volumes:
63 - redis-data:/data
64 healthcheck:
65 test: ["CMD", "redis-cli", "ping"]
66 interval: 10s
67 timeout: 3s
68 retries: 3
69 networks:
70 - roman-network
71
72 # === Nginx Reverse Proxy ===
73 nginx:
74 image: nginx:alpine
75 container_name: roman-nginx
76 restart: unless-stopped
77 ports:
78 - "80:80"
79 volumes:
80 - ./nginx.conf:/etc/nginx/nginx.conf:ro
81 depends_on:
82 - api
83 networks:
84 - roman-network
85
86# Volumes
87volumes:
88 mongo-data:
89 driver: local
90 redis-data:
91 driver: local
92
93# Network
94networks:
95 roman-network:
96 driver: bridge
97
98# Komendy:
99# docker-compose up -d # Uruchom
100# docker-compose logs -f api # Logi API
101# docker-compose down # Zatrzymaj
102# docker-compose ps # Status
103Widzisz błąd w tej lekcji?