Docker dla Node.js i Next.js
Multi-stage Dockerfile, Docker Compose (Postgres, Redis), GitHub Actions CI/CD i Kubernetes basics — konteneryzacja aplikacji Node.js.
6 konceptów Docker dla Node.js — porównanie
Multi-stage Dockerfile, Docker Compose, GitHub Actions, non-root user, health checks i Kubernetes — zastosowanie, przykład i kiedy używać.
| Koncept | Zastosowanie | Przykład | Kiedy |
|---|---|---|---|
| Multi-stage Dockerfile | Mniejszy obraz produkcyjny | deps -> builder -> runner | Zawsze dla Next.js/Node.js |
| Docker Compose | Wielokontenerowe środowiska | app + postgres + redis | Lokalne dev, staging |
| GitHub Actions CI/CD | Build, test, push, deploy | docker/build-push-action | Automatyzacja pipeline |
| Non-root user | Bezpieczeństwo kontenera | adduser appuser; USER appuser | Zawsze w produkcji |
| Health checks | Monitoring i restarts | HEALTHCHECK CMD wget /health | Produkcja, K8s readiness |
| Kubernetes Deployment | Skalowanie, self-healing | replicas: 3, HPA | Skala produkcyjna, enterprise |
Często zadawane pytania
Jak zbudować optymalny Dockerfile dla Node.js i Next.js?
Podstawowy Dockerfile Node.js: FROM node:20-alpine. WORKDIR /app. COPY package*.json ./. RUN npm ci --only=production. COPY . .. EXPOSE 3000. CMD ['node', 'server.js']. Alpine base: mniejszy obraz (~180MB vs ~900MB). Brak wielu narzędzi — lżejszy. Bezpieczniejszy. Multi-stage build (best practice): Stage 1 — deps: FROM node:20-alpine AS deps. WORKDIR /app. COPY package*.json ./. RUN npm ci. Stage 2 — builder: FROM node:20-alpine AS builder. WORKDIR /app. COPY --from=deps /app/node_modules ./node_modules. COPY . .. RUN npm run build. Stage 3 — runner: FROM node:20-alpine AS runner. WORKDIR /app. ENV NODE_ENV=production. COPY --from=builder /app/.next/standalone ./. COPY --from=builder /app/.next/static ./.next/static. COPY --from=builder /app/public ./public. EXPOSE 3000. CMD ['node', 'server.js']. Next.js standalone output: next.config.js: output: 'standalone'. Minimalny bundle. Serwer w .next/standalone. Nie wymaga pełnego node_modules. Layer caching: COPY package*.json najpierw. RUN npm ci. Potem COPY . .. Jeśli tylko kod się zmienia — layer deps z cache. Szybszy build. .dockerignore: node_modules, .next, .env, .git, *.log. Nie kopiuj do kontenera.
Docker Compose dla Node.js, Postgres i Redis?
Docker Compose: wielokontenerowe aplikacje. docker-compose.yml: services: app: build: .. ports: ['3000:3000']. environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb - REDIS_URL=redis://redis:6379. depends_on: db: condition: service_healthy. redis:. networks: [app-network]. db: image: postgres:16-alpine. volumes: [pgdata:/var/lib/postgresql/data]. environment: POSTGRES_DB: mydb. POSTGRES_USER: user. POSTGRES_PASSWORD: password. healthcheck: test: ['CMD-SHELL', 'pg_isready -U user']. interval: 5s. timeout: 5s. retries: 5. redis: image: redis:7-alpine. volumes: [redisdata:/data]. networks: [app-network]. volumes: pgdata:. redisdata:. networks: app-network: driver: bridge. Komendy: docker compose up -d — start. docker compose down — stop. docker compose logs -f app — logi. docker compose exec app sh — shell w kontenerze. docker compose build --no-cache. Health checks: healthcheck na db i redis. depends_on z condition: service_healthy. Unikaj race condition. Sekretne zmienne: .env file. docker compose --env-file .env. Nie commituj .env z secretami. Development vs Production Compose: docker-compose.yml — base. docker-compose.override.yml — dev (volumes, hot reload). docker-compose.prod.yml — prod (no volumes). docker compose -f docker-compose.yml -f docker-compose.prod.yml up.
GitHub Actions — CI/CD dla Node.js i Docker?
GitHub Actions Dockerfile build i push do registry: name: Build and Push. on: push: branches: [main]. jobs: build: runs-on: ubuntu-latest. steps: - uses: actions/checkout@v4. - uses: docker/setup-buildx-action@v3. - uses: docker/login-action@v3. with: registry: ghcr.io. username: ${{ github.actor }}. password: ${{ secrets.GITHUB_TOKEN }}. - uses: docker/build-push-action@v5. with: push: true. tags: ghcr.io/${{ github.repository }}:latest. cache-from: type=gha. cache-to: type=gha,mode=max. Build cache — szybsze buildy. Test before build: steps: - uses: actions/setup-node@v4. with: node-version: '20'. cache: 'npm'. - run: npm ci. - run: npm test. - run: npm run lint. - run: npm run build. Node.js cache: actions/setup-node z cache: 'npm'. Automatyczny cache node_modules. Docker layer cache w GitHub Actions: cache-from/cache-to type=gha. Zaoszczędź minuty build. Deploy na VPS (SSH): - name: Deploy. uses: appleboy/ssh-action@v1. with: host: ${{ secrets.HOST }}. username: ${{ secrets.USERNAME }}. key: ${{ secrets.SSH_KEY }}. script: docker pull image:latest && docker compose up -d. Deploy na Railway/Render/Fly.io: automatyczne z GitHub. Bez pisania CI. Dobre dla start. Kubernetes deploy: kubectl set image deployment/app app=image:tag. lub Helm upgrade. Secrets management: GitHub Secrets. Nie secrets w code. Environment variables w Compose.
Optymalizacja Node.js w Docker — performance i security?
Non-root user: RUN addgroup -S appgroup && adduser -S appuser -G appgroup. USER appuser. Nie uruchamiaj jako root! Security best practice. Read-only filesystem: docker run --read-only. Mounts dla writable dirs: --tmpfs /tmp. Nie pisz do kontenera poza volumes. Secrets w runtime: nie w ENV w Dockerfile. docker secret (Swarm). Kubernetes Secrets. W runtime przez env (z Compose lub K8s). Node.js process manager: Nie potrzebujesz PM2 w Docker (Docker restartuje). NODE_ENV=production — wyłącz dev dependencies. --restart unless-stopped w Docker run. tini jako PID 1: FROM node:20-alpine. RUN apk add tini. ENTRYPOINT ['/sbin/tini', '--']. CMD ['node', 'server.js']. Signal handling. Graceful shutdown. Memory limits: docker run --memory=512m. Node.js heap size: NODE_OPTIONS='--max-old-space-size=512'. Unikaj OOM kills. Image scanning: docker scout cves image:tag. Trivy — open source scanner. Snyk Container. GitHub Actions: trivy-action. Log management: stdout/stderr do Docker. docker logs. Fluentd/Loki aggregation. Brak pliku log w kontenerze. Healthcheck w Dockerfile: HEALTHCHECK --interval=30s --timeout=3s CMD wget -O- http://localhost:3000/health || exit 1. /health endpoint w Express. Kubernetes readiness i liveness probes. Resource requests i limits w K8s: resources: requests: memory: 256Mi, cpu: 250m. limits: memory: 512Mi, cpu: 500m. Distroless images: gcr.io/distroless/nodejs20. Minimalny image. Brak shell. Bardzo bezpieczny. Brak apk/apt.
Kubernetes basics dla Node.js/Next.js aplikacji?
Kubernetes (K8s): orkestracja kontenerów. Deployment, scaling, healing. Self-healing — restart crashed pods. Rolling updates — zero downtime. Secrets i ConfigMaps. Podstawowe obiekty: Pod — najmniejsza jednostka. Deployment — zarządza Pods. Service — load balancer. Ingress — HTTP routing. ConfigMap — konfiguracja. Secret — wrażliwe dane. PersistentVolume — storage. Deployment YAML: apiVersion: apps/v1. kind: Deployment. metadata: name: app. spec: replicas: 3. selector: matchLabels: app: myapp. template: metadata: labels: app: myapp. spec: containers: - name: app. image: ghcr.io/user/app:latest. ports: [{containerPort: 3000}]. env: [{name: DATABASE_URL, valueFrom: {secretKeyRef: {name: app-secrets, key: DATABASE_URL}}}]. resources: requests: {memory: 256Mi}. limits: {memory: 512Mi}. Service YAML: kind: Service. spec: selector: app: myapp. ports: [{port: 80, targetPort: 3000}]. type: ClusterIP. Ingress z Nginx: kind: Ingress. annotations: nginx.ingress.kubernetes.io/ssl-redirect: 'true'. spec: rules: [{host: myapp.com, http: {paths: [{path: /, backend: {service: {name: app, port: {number: 80}}}}]}}]. Horizontal Pod Autoscaler: kubectl autoscale deployment app --min=2 --max=10 --cpu-percent=70. Skalowanie po obciążeniu. Managed K8s: GKE, EKS, AKS — bez zarządzania control plane. Alternatywy: Railway, Render, Fly.io — simpler than K8s. Dobry wybór dla małych apps. K8s — enterprise scale.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz