Architektury nasazení a životní cyklus Node.js aplikace
Nasazení Node.js aplikací na server zahrnuje volbu architektury (single host, kontejnery, orchestrátor), způsob běhu procesu, reverzní proxy, škálování, observability a automatizace. Typický životní cyklus zahrnuje build (transpilaci/kompilaci 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 využití vícejádrových procesorů použijte procesní model (více instancí) nebo cluster v kombinaci s procesovým manažerem.
- systemd – standardní správce služeb na Linuxu; nabízí restart, logging (journald), watchdog a sandboxing.
- PM2 – pohodlný procesový manažer s cluster mode, rotací logů a jednoduchým zero-downtime reload.
- Node cluster – vytváří worker procesy sdílející port; preferujte jeho použití 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 interním portu (např. 3000). Reverzní proxy:
- terminuje TLS (Let’s Encrypt),
- zajišťuje bezpečnostní hlavičky (HSTS, CSP, CORS),
- provádí rate limiting a kompresi,
- balancuje zatížení 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í usnadňuje správu závislostí a zajišťuje reprodukovatelnost. Doporučení:
- Multi-stage build – oddělte build a runtime image; používejte Alpine/Distroless pro malé obrazy.
- Neprivilegovaný uživatel – nastavte
USER nodea používejte porty nad 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:
- Linting/testy (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žňuje plynulé přepnutí workerů bez výpadku (graceful restart).
Graceful shutdown a signal handling
Správná obsluha signálu SIGTERM zamezí přerušení zpracovávaný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_URLatd.). Citlivá data nikdy neukládejte do repozitáře. - Secret management – OS úložiště (
systemdEnvironmentFile s přístupovými právy), Vault, SOPS + KMS, Docker/Kubernetes Secrets. - Konfigurační validace – validační schéma při startu (např. Zod/TypeBox) a fail-fast chování.
Databáze a migrace schématu
Produkční nasazení vyžaduje bezpečný a bezvýpadkový postup migrací:
- Bez výpadku – měňte schéma kompatibilně (přidání sloupců s defaultní hodnotou, backfill dat, následné přepnutí kódu).
- Nástroje – Prisma Migrate, Knex, TypeORM, Flyway. Logujte verze migrací a zachovávejte idempotentnost.
- Poolování – správně nastavte velikost poolu, timeouty a backoff (např. pg, mysql2).
Cache, CDN a výkon
- HTTP cache – používejte
ETag,Cache-Control,Vary. Reverzní proxy může cachovat idempotentní GET požadavky. - Aplikační cache – Redis/Memcached pro náročné dotazy; invalidace na změnu dat (eventy, TTL).
- Profilace –
clinic.js,0x,node --prof; sledujte garbage collection, event loop lag a alokace paměti.
WebSockety, SSE a sticky sessions
Pro real-time aplikace je nezbytná správná konfigurace proxy a škálování:
- Upgrade hlavičky – Nginx musí povolit
Connection: upgradeaUpgrade: websocket. - Sticky routing – u WS často vyžadován; jinak sdílejte stav přes Redis (Socket.IO adapter) nebo použijte pub/sub mechanizmy.
- SSE – jednodušší než WS, ale pozor na limity paralelních spojení a timeouts.
Observability: logování, metriky, trace
- Strukturované logy – JSON formát (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 chyby 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, ochrana proti XSS, no-sniff), omezení HTTP metod a velikostí payloadů. - Rate limiting – v proxy i aplikaci; ochrana proti brute-force a DoS útokům.
- Secrets – nikdy neukládejte do logů; pravidelně rotujte klíče, používejte krátkodobé tokeny (OIDC).
- Sandboxing – systemd 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é rozšíření.
- 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 týmu.
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ů bez výpadku.
Migrace bez výpadku a řízení verzí API
- Zpětná kompatibilita – nasazujte kód, který podporuje stará i nová pole. Teprve poté proveďte nepřímé změny v databázi s »breaking« charakterem.
- Verzování API – použijte namespace jako
/v1,/v2nebo content negotiation; dokumentujte pomocí OpenAPI.
Zálohy, obnova a disaster recovery
- Runbooky – dokumentované postupy pro incidenty, rollback a obnovu.
- Zálohy – pravidelné snapshoty databází a objektových storage, ověřování obnovy („fire drill“).
- Multi-region – pro kritické služby replikace dat a failover provozu mezi regiony.
Řízení nákladů a efektivita
- Profilování – identifikujte výkonové úzká místa dříve, než navýšíte klastr.
- Autoscaling a plánování – přizpůsobte kapacitu



























