Architektury nasazení a životní cyklus Node.js aplikace
Nasazení Node.js aplikací na server zahrnuje volbu architektury (single host, kontejnery, orchestrátor), způsobu běhu procesu, reverzního proxy, škálování, observability a automatizace. Typický životní cyklus zahrnuje build (transpilace/kompilace TypeScriptu), přípravu prostředí (proměnné, tajemství), rollout (zero-downtime), monitoring a rollback. Správná volba cíle (VPS, bare metal, PaaS, Kubernetes) se řídí požadavky na SLA, propustnost, rozpočet a týmové dovednosti.
Volba runtime a správa verzí Node.js
- LTS vs. Current – v produkci preferujte LTS kvůli stabilitě knihoven a bezpečnostním aktualizacím.
- Správa verzí – nástroje nvm, fnm nebo asdf pro vývoj; v produkci fixujte verzi přes systémové balíčky,
Dockerfilebase image, nebo binární distribuci (např.node:20-alpine). - ESM vs. CommonJS – sjednoťte modulový systém; pro ESM nastavte
"type": "module"a sladěné bundlery.
Příprava aplikace: build, bundling a artefakty
- TypeScript – transpilujte do
dist/a nasazujte pouze artefakty (nikolinode_modulesz vývoje). Zvažte tsup/esbuild pro rychlý bundling. - Pruning závislostí – používejte
npm ci --omit=devnebopnpm install --prodv CI pro minimalizaci obrazu či balíčku. - Determinizmus – commitujte
package-lock.json/pnpm-lock.yamla sledujteNODE_OPTIONS=--conditions=productiondle potřeby.
Procesní model: systemd, PM2 a cluster
Node.js běží jako single-thread event loop. Pro multi-core využití použijte procesní model (více instancí) nebo cluster v kombinaci s process managerem.
- systemd – standardní správce služby na Linuxu; nabízí restart, logging (journald), watchdog a sandboxing.
- PM2 – pohodlný process manager s cluster mode, logrotací a jednoduchým zero-downtime reload.
- Node cluster – vytváří worker procesy sdílející port; preferujte přes nástroj (PM2), který řeší životní cyklus.
Ukázka systemd jednotky:
[Unit] Description=My Node.js API After=network.target [Service] Environment=NODE_ENV=production EnvironmentFile=/etc/myapi.env WorkingDirectory=/srv/myapi ExecStart=/usr/bin/node dist/server.js Restart=always RestartSec=3 User=node Group=node # Bezpečnostní omezení NoNewPrivileges=true ProtectSystem=full ProtectHome=true PrivateTmp=true AmbientCapabilities= [Install] WantedBy=multi-user.target
Reverzní proxy: Nginx / Caddy jako terminátor TLS a load balancer
Node server (např. Fastify/Express) typicky běží na vnitřním portu (např. 3000). Reverzní proxy:
- terminuje TLS (Let’s Encrypt),
- zabezpečuje hlavičky (HSTS, CSP, CORS),
- provádí rate limiting a kompresi,
- balancuje mezi více instancemi (upstream pool).
Ukázka Nginx konfigurace:
upstream myapi { server 127.0.0.1:3001; server 127.0.0.1:3002; keepalive 64; } server { listen 80; server_name api.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name api.example.com; ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options DENY; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; location / { proxy_pass http://myapi; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_read_timeout 60s; } }
Dockerizace a immutable nasazení
Kontejnerové nasazení zjednodušuje závislosti a reprodukovatelnost. Doporučení:
- Multi-stage build – oddělte build a run image; používejte Alpine/Distroless pro malé obrazy.
- Neprivilegovaný uživatel – nastavte
USER nodea odemkněte port >1024 (např. 3000). - Healthcheck – definujte HTTP endpoint pro liveness/readiness.
Příklad Dockerfile:
# Build stage FROM node:20-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build && npm prune --omit=dev # Runtime stage FROM node:20-alpine ENV NODE_ENV=production WORKDIR /app COPY --from=build /app/package*.json ./ COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/dist ./dist USER node EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://127.0.0.1:3000/health || exit 1 CMD ["node", "dist/server.js"]
CI/CD: build, test, audit a rollout
Pipeline by měla obsahovat:
- Lint/test (unit, e2e), SCA (
npm audit,osv), SAST. - Build artefaktu (tarball/Docker image) a jeho podepsání (Sigstore/cosign).
- Deploy na staging, smoke testy, následně produkce (blue-green/canary).
Ukázka GitHub Actions (zkráceně):
name: ci on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 20, cache: 'npm' } - run: npm ci - run: npm run lint && npm test - run: npm run build - run: npm prune --omit=dev - name: Build image run: docker build -t ghcr.io/org/myapi:${{ github.sha }} .
Zero-downtime release: blue-green a canary
- Blue-green – provozují se dvě identické verze (blue a green). Po validaci přepněte traffic (Nginx upstream, load balancer) a starou verzi ukončete.
- Canary – nasadíte malému procentu uživatelů; sledujete metriky a postupně zvyšujete podíl.
- PM2 reload – umožní plynulé přepnutí workerů bez výpadku (graceful).
Graceful shutdown a signal handling
Správná obsluha SIGTERM zamezí přerušení rozpracovaných požadavků a poškození transakcí.
import http from 'node:http'; import { pool } from './db.js'; // příklad: pg/pool const server = http.createServer(app); const PORT = process.env.PORT ?? 3000; server.listen(PORT, () => console.log(`Listening on ${PORT}`)); let shuttingDown = false; process.on('SIGTERM', async () => { if (shuttingDown) return; shuttingDown = true; console.log('SIGTERM received. Starting graceful shutdown...'); server.close(async () => { try { await pool.end(); // uzavřít DB pool console.log('Shutdown complete.'); process.exit(0); } catch (e) { console.error('Error during shutdown', e); process.exit(1); } }); // volitelně: po X sekundách vynutit exit setTimeout(() => process.exit(1), 10000).unref(); });
Konfigurace, tajemství a prostředí
- 12-factor – konfiguraci držte v proměnných prostředí (
DATABASE_URL,REDIS_URL, …). Nepřidávejte citlivá data do repozitáře. - Secret management – OS úložiště (
systemdEnvironmentFile s právy), Vault, SOPS + KMS, Docker/K8s Secrets. - Konfigurační validace – schema validace při startu (Zod/TypeBox) a fail-fast.
Databáze a migrace schématu
Produkční nasazení vyžaduje bezpečný postup migrací:
- Bez výpadku – měňte schéma kompatibilně (přidání sloupců s defaultem, backfill, následné přepnutí kódu).
- Nástroje – Prisma Migrate, Knex, TypeORM, Flyway. Logujte verze migrací a držte je idempotentní.
- Poolování – správně nastavte velikost poolu, timeouty a backoff (např. pg, mysql2).
Cache, CDN a performance
- HTTP cache – používejte
ETag,Cache-Control,Vary. Reverzní proxy může cachovat idempotentní GET. - Aplikační cache – Redis/Memcached pro drahé dotazy; invalidace na změnu dat (eventy, TTL).
- Profilace –
clinic.js,0x,node --prof; sledujte GC, event loop lag a alokace.
WebSockety, SSE a sticky sessions
Pro real-time je nutná správná konfigurace proxy a škálování:
- Upgrade hlavičky – Nginx musí povolit
Connection: upgradeaUpgrade: websocket. - Sticky routing – u WS často vyžadováno; jinak sdílejte stav přes Redis (Socket.IO adapter) či použijte pub/sub.
- SSE – jednodušší než WS, ale pozor na limity paralelních spojení a timeouts.
Observability: logování, metriky, trace
- Strukturované logy – JSON (pino/winston), unikátní request-id, korelace přes
X-Request-ID. - Metriky – Prometheus endpoint (p95 latence, error rate, throughput), scrapování a dashboardy (Grafana).
- Tracing – OpenTelemetry pro distribuovaný tracing; export do Jaeger/Tempo/OTLP.
- Alerting – SLO/SLI (např. 99.9 % dostupnosti), alerty na chybovost a saturaci zdrojů.
Bezpečnost produkce
- Závislosti – pravidelné aktualizace, audit, blokování známých CVE (npm
audit-level), Dependabot. - HTTP hlavičky –
Helmet(CSP, HSTS, XSS protection, no-sniff), omezení metod a velikostí payloadů. - Rate limiting – v proxy i aplikaci, ochrana proti brute-force a DoS.
- Secrets – nikdy v logu; rotate klíče pravidelně, používejte krátkodobé tokeny (OIDC).
- Sandboxing –
systemdomezení, seccomp v Dockeru, read-only filesystem, drop capabilities.
Škálování: vertikální, horizontální a Kubernetes
- Vertikální – navyšování CPU/RAM; rychlé, ale limitované.
- Horizontální – více instancí za load balancerem; stateless design (session do Redis/DB, soubory do objektového úložiště).
- Kubernetes – auto-healing, autoscaling (HPA), rolling updates; vyžaduje vyšší provozní zralost.
PM2 ekosystém a zero-downtime reload
Příklad ecosystem.config.js:
module.exports = { apps: [{ name: "myapi", script: "dist/server.js", instances: "max", exec_mode: "cluster", env: { NODE_ENV: "production" }, watch: false, max_memory_restart: "512M" }] };
Nasazení: pm2 start ecosystem.config.js, rollout: pm2 reload myapi pro plynulý restart workerů.
Migrace bez výpadku a řízení verzí API
- Backward compatibility – nasazujte kód, který rozumí starým i novým polím. Teprve poté proveďte DB změny „breaking“ charakteru.
- Verzování API –
/v1,/v2nebo pomocí content negotiation; dokumentujte přes OpenAPI.
Zálohy, obnova a disaster recovery
- Runbooky – dokumentovaný postup pro incidenty, rollback a obnovu.
- Zálohy – pravidelné snapshoty DB a objektového úložiště, test obnovy (fire drill).
- Multi-region – pro kritické služby replikace dat a traffic failover.
Řízení nákladů a efektivita
- Profilování – odhalte hotspoty dříve, než zvětšíte cluster.
- Autoscaling a plánování – přizpůsobte kapacitu denním špičkám, vypínejte přebytečné instance mimo špičku.
- Efektivní logování – sampling a retence; velké objemy logů jsou nákladné.
Checklist pro produkční nasazení
- Build artefakt je reprodukovatelný, obsahuje pouze runtime závislosti.
- Proces je spravován (systemd/PM2/K8s), má healthcheck a graceful shutdown.
- Reverzní proxy terminují TLS, aplikují bezpečnostní hlavičky a rate limiting.
- Konfigurace přes proměnné prostředí, tajemství mimo repozitář, validace při startu.
- Migrace schématu jsou automatizované a kompatibilní, rollback je nacvičen.
- Monitoring: logy, metriky, trace; alerty navázané na SLO.
- Rollout strategie (blue-green/canary) a automatizovaný rollback.
- Dokumentované runbooky a testované zálohy.
Závěr
Robustní nasazení Node.js aplikací na server kombinuje opakovatelné buildy, bezpečný běh procesu, správnou síťovou vrstvu, automatizované release postupy a bohatou observabilitu. Vytvořením standardizovaného pipeline a provozního „guard-rail“ ekosystému získáte prediktivní výkon, nižší riziko incidentů a možnost škálovat od jednoho serveru po distribuovaný multiregionální cluster.