Nasazení Node.js

Nasazení Node.js

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, Dockerfile base 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 (nikoli node_modules z vývoje). Zvažte tsup/esbuild pro rychlý bundling.
  • Pruning závislostí – používejte npm ci --omit=dev nebo pnpm install --prod v CI pro minimalizaci obrazu či balíčku.
  • Determinizmus – commitujte package-lock.json/pnpm-lock.yaml a sledujte NODE_OPTIONS=--conditions=production dle 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 node a 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:

  1. Lint/test (unit, e2e), SCA (npm audit, osv), SAST.
  2. Build artefaktu (tarball/Docker image) a jeho podepsání (Sigstore/cosign).
  3. 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ě (systemd EnvironmentFile 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).
  • Profilaceclinic.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: upgrade a Upgrade: 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čkyHelmet (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).
  • Sandboxingsystemd omezení, 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, /v2 nebo 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.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *