nodejs-app

Deploy a Node.js application - supports PM2, systemd, Docker, or Kubernetes

Recipaie - 배포 레시피

이 서비스를 어떻게 배포하는지 설명하는 템플릿입니다.

원본 JSON
{
  "$schema": "https://recipaie.com/schemas/recipaie.schema.json",
  "name": "nodejs-app",
  "version": "1.0.0",
  "description": "Deploy a Node.js application - supports PM2, systemd, Docker, or Kubernetes",
  "prerequisites": [
    "Node.js 18+ runtime (unless using containerized deployment)",
    "Application source code or container image",
    "One of: PM2 process manager, systemd, Docker, or Kubernetes"
  ],
  "steps": [
    {
      "order": 1,
      "what": "Assess deployment environment",
      "why": "Node.js apps can run in many ways - choose what fits your infrastructure",
      "when": "Before deployment",
      "how": "Evaluate options: (1) PM2 - simple process manager with clustering and monitoring, (2) systemd - native Linux service management, (3) Docker - containerized isolation, (4) Kubernetes - orchestrated containers. Consider: existing infrastructure, scaling needs, monitoring requirements",
      "verify": "Deployment method chosen based on infrastructure assessment",
      "comments": [
        "PM2 is simplest for single-server deployments",
        "systemd integrates with Linux service management",
        "Docker/K8s best for consistent environments and horizontal scaling"
      ]
    },
    {
      "order": 2,
      "what": "Install Node.js runtime",
      "why": "Required for PM2 and systemd deployments (containers include runtime)",
      "when": "If using PM2 or systemd deployment",
      "skip_if": "Using Docker/K8s (runtime included in image), or Node.js already at required version",
      "how": "Install via package manager: (Ubuntu) curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt install nodejs, (RHEL) dnf module install nodejs:20, (macOS) brew install node@20, (nvm) nvm install 20",
      "verify": "node --version shows v20.x or higher",
      "comments": [
        "Use LTS versions for production (20.x, 22.x)",
        "nvm allows multiple Node versions on same machine",
        "Consider using mise or asdf for polyglot version management"
      ]
    },
    {
      "order": 3,
      "what": "Prepare application",
      "why": "Application needs dependencies and build artifacts",
      "when": "Before running the application",
      "skip_if": "Using pre-built container image with all dependencies",
      "how": "Clone repo or copy source, then: npm ci --production (or npm install --production). If TypeScript or build step required: npm run build",
      "verify": "node_modules exists, build artifacts present if applicable",
      "comments": [
        "npm ci is faster and more reliable than npm install for CI/CD",
        "Use --production to skip devDependencies",
        "For containers: multi-stage build to keep image small"
      ]
    },
    {
      "order": 4,
      "what": "Configure environment variables",
      "why": "12-factor app configuration via environment",
      "when": "Before starting the application",
      "how": "Set required environment variables: NODE_ENV=production, PORT=3000, plus app-specific config. Method depends on deployment: (PM2) ecosystem.config.js env section, (systemd) Environment= in unit file, (Docker) -e flags or env_file, (K8s) ConfigMap/Secret",
      "verify": "Environment variables accessible to application process",
      "comments": [
        "Never commit secrets to source control",
        "Use secret management for sensitive values (Vault, AWS Secrets Manager, K8s Secrets)",
        "Consider .env files for local development only"
      ]
    },
    {
      "order": 5,
      "what": "Deploy and start application",
      "why": "Run the application with your chosen method",
      "when": "After application is prepared",
      "how": "Start using chosen method: (PM2) pm2 start ecosystem.config.js && pm2 save, (systemd) systemctl start myapp && systemctl enable myapp, (Docker) docker run -d --name myapp -p 3000:3000 myapp:latest, (K8s) kubectl apply -f deployment.yaml",
      "verify": "curl http://localhost:3000/health returns success response",
      "comments": [
        "PM2: use pm2 startup to configure boot persistence",
        "systemd: create /etc/systemd/system/myapp.service unit file",
        "Always implement a health check endpoint"
      ]
    },
    {
      "order": 6,
      "what": "Configure process management and monitoring",
      "why": "Ensure application restarts on crash and is monitored",
      "when": "After initial deployment succeeds",
      "skip_if": "Orchestrator handles this (K8s has built-in restart policies)",
      "how": "Configure restart policies: (PM2) automatic with configurable max restarts, (systemd) Restart=always in unit file, (Docker) --restart=unless-stopped. Set up monitoring: PM2 has built-in metrics, or use external APM (Datadog, New Relic, etc.)",
      "verify": "Kill the app process - it should automatically restart within seconds",
      "comments": [
        "PM2: pm2 monit for real-time monitoring",
        "Consider log aggregation (publog, ELK, CloudWatch)",
        "Set up alerting for downtime and error rates"
      ]
    }
  ],
  "step_count": 6
}
버전: 1.0.0
단계 수: 6

사전 조건

단계

1 Assess deployment environment
이유
Node.js apps can run in many ways - choose what fits your infrastructure
시점
Before deployment
방법
Evaluate options: (1) PM2 - simple process manager with clustering and monitoring, (2) systemd - native Linux service management, (3) Docker - containerized isolation, (4) Kubernetes - orchestrated containers. Consider: existing infrastructure, scaling needs, monitoring requirements
검증
Deployment method chosen based on infrastructure assessment
비고
  • PM2 is simplest for single-server deployments
  • systemd integrates with Linux service management
  • Docker/K8s best for consistent environments and horizontal scaling
2 Install Node.js runtime
이유
Required for PM2 and systemd deployments (containers include runtime)
시점
If using PM2 or systemd deployment
건너뛰는 조건
Using Docker/K8s (runtime included in image), or Node.js already at required version
방법
Install via package manager: (Ubuntu) curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt install nodejs, (RHEL) dnf module install nodejs:20, (macOS) brew install node@20, (nvm) nvm install 20
검증
node --version shows v20.x or higher
비고
  • Use LTS versions for production (20.x, 22.x)
  • nvm allows multiple Node versions on same machine
  • Consider using mise or asdf for polyglot version management
3 Prepare application
이유
Application needs dependencies and build artifacts
시점
Before running the application
건너뛰는 조건
Using pre-built container image with all dependencies
방법
Clone repo or copy source, then: npm ci --production (or npm install --production). If TypeScript or build step required: npm run build
검증
node_modules exists, build artifacts present if applicable
비고
  • npm ci is faster and more reliable than npm install for CI/CD
  • Use --production to skip devDependencies
  • For containers: multi-stage build to keep image small
4 Configure environment variables
이유
12-factor app configuration via environment
시점
Before starting the application
방법
Set required environment variables: NODE_ENV=production, PORT=3000, plus app-specific config. Method depends on deployment: (PM2) ecosystem.config.js env section, (systemd) Environment= in unit file, (Docker) -e flags or env_file, (K8s) ConfigMap/Secret
검증
Environment variables accessible to application process
비고
  • Never commit secrets to source control
  • Use secret management for sensitive values (Vault, AWS Secrets Manager, K8s Secrets)
  • Consider .env files for local development only
5 Deploy and start application
이유
Run the application with your chosen method
시점
After application is prepared
방법
Start using chosen method: (PM2) pm2 start ecosystem.config.js && pm2 save, (systemd) systemctl start myapp && systemctl enable myapp, (Docker) docker run -d --name myapp -p 3000:3000 myapp:latest, (K8s) kubectl apply -f deployment.yaml
검증
curl http://localhost:3000/health returns success response
비고
  • PM2: use pm2 startup to configure boot persistence
  • systemd: create /etc/systemd/system/myapp.service unit file
  • Always implement a health check endpoint
6 Configure process management and monitoring
이유
Ensure application restarts on crash and is monitored
시점
After initial deployment succeeds
건너뛰는 조건
Orchestrator handles this (K8s has built-in restart policies)
방법
Configure restart policies: (PM2) automatic with configurable max restarts, (systemd) Restart=always in unit file, (Docker) --restart=unless-stopped. Set up monitoring: PM2 has built-in metrics, or use external APM (Datadog, New Relic, etc.)
검증
Kill the app process - it should automatically restart within seconds
비고
  • PM2: pm2 monit for real-time monitoring
  • Consider log aggregation (publog, ELK, CloudWatch)
  • Set up alerting for downtime and error rates

Prodaie - 실행 기록

AI가 이 레시피를 서로 다른 환경에서 실행했을 때 일어난 일입니다.

핵심 차이: 각 단계에는

success

(bool) 및

details

(string) 필드가 추가되어 실제로 무슨 일이 있었는지 기록합니다.

원본 JSON
{
  "$schema": "https://recipaie.com/schemas/prodaie.schema.json",
  "name": "nodejs-app",
  "description": "Deployment record showing Node.js app deployed via different methods: PM2, Docker, and Kubernetes",
  "prerequisites": [
    "Node.js 18+ runtime (unless using containerized deployment)",
    "Application source code or container image",
    "One of: PM2 process manager, systemd, Docker, or Kubernetes"
  ],
  "locations": [
    {
      "path": "dev-server (PM2)",
      "description": "Single development server using PM2 for process management",
      "status": "complete",
      "step_count": 6,
      "steps": [
        {
          "order": 1,
          "what": "Assess deployment environment",
          "why": "Node.js apps can run in many ways - choose what fits your infrastructure",
          "when": "Before deployment",
          "how": "Evaluate options: PM2, systemd, Docker, or Kubernetes",
          "verify": "Deployment method chosen based on infrastructure assessment",
          "success": true,
          "details": "chose PM2 for simplicity, already familiar with ecosystem.config.js"
        },
        {
          "order": 2,
          "what": "Install Node.js runtime",
          "why": "Required for PM2 and systemd deployments",
          "when": "If using PM2 or systemd deployment",
          "skip_if": "Using Docker/K8s or Node.js already at required version",
          "how": "Install via package manager or nvm",
          "verify": "node --version shows v20.x or higher",
          "success": true,
          "details": "nvm install 20 && nvm use 20, shows v20.10.0"
        },
        {
          "order": 3,
          "what": "Prepare application",
          "why": "Application needs dependencies and build artifacts",
          "when": "Before running the application",
          "skip_if": "Using pre-built container image",
          "how": "npm ci --production, then npm run build if needed",
          "verify": "node_modules exists, build artifacts present",
          "success": true,
          "details": "npm ci --production && npm run build, dist/ folder created"
        },
        {
          "order": 4,
          "what": "Configure environment variables",
          "why": "12-factor app configuration via environment",
          "when": "Before starting the application",
          "how": "Set NODE_ENV=production, PORT, and app-specific config in ecosystem.config.js",
          "verify": "Environment variables accessible to application process",
          "success": true,
          "details": "added env section to ecosystem.config.js with NODE_ENV=production, PORT=3000"
        },
        {
          "order": 5,
          "what": "Deploy and start application",
          "why": "Run the application with your chosen method",
          "when": "After application is prepared",
          "how": "pm2 start ecosystem.config.js && pm2 save",
          "verify": "curl http://localhost:3000/health returns success",
          "success": true,
          "details": "pm2 start ecosystem.config.js, /health returns {\"status\":\"ok\"}"
        },
        {
          "order": 6,
          "what": "Configure process management and monitoring",
          "why": "Ensure application restarts on crash and is monitored",
          "when": "After initial deployment succeeds",
          "skip_if": "Orchestrator handles this",
          "how": "Configure restart policies and monitoring",
          "verify": "Kill the app process - it should restart automatically",
          "success": true,
          "details": "pm2 startup configured, tested kill -9 and app restarted in 2s"
        }
      ]
    },
    {
      "path": "staging-cluster (Docker)",
      "description": "Docker deployment on staging cluster",
      "status": "complete",
      "step_count": 6,
      "steps": [
        {
          "order": 1,
          "what": "Assess deployment environment",
          "why": "Node.js apps can run in many ways",
          "when": "Before deployment",
          "how": "Evaluate options based on infrastructure",
          "verify": "Deployment method chosen",
          "success": true,
          "details": "chose Docker for consistent environment with production"
        },
        {
          "order": 2,
          "what": "Install Node.js runtime",
          "why": "Required for PM2 and systemd deployments",
          "when": "If using PM2 or systemd deployment",
          "skip_if": "Using Docker/K8s",
          "how": "Install via package manager",
          "verify": "node --version shows v20.x",
          "success": true,
          "details": "using Docker, Node.js included in container image"
        },
        {
          "order": 3,
          "what": "Prepare application",
          "why": "Application needs dependencies and build artifacts",
          "when": "Before running the application",
          "skip_if": "Using pre-built container image",
          "how": "npm ci --production, npm run build",
          "verify": "Build artifacts present",
          "success": true,
          "details": "multi-stage Dockerfile builds image with npm ci && npm run build, final image 145MB"
        },
        {
          "order": 4,
          "what": "Configure environment variables",
          "why": "12-factor app configuration",
          "when": "Before starting the application",
          "how": "Set environment variables via docker run -e or env_file",
          "verify": "Environment variables accessible",
          "success": true,
          "details": "created .env.staging with all config, using --env-file in docker run"
        },
        {
          "order": 5,
          "what": "Deploy and start application",
          "why": "Run the application",
          "when": "After application is prepared",
          "how": "docker run -d --name myapp -p 3000:3000 myapp:latest",
          "verify": "curl http://localhost:3000/health returns success",
          "success": true,
          "details": "docker run -d --name api-staging -p 3000:3000 --env-file .env.staging myapp:v1.2.3"
        },
        {
          "order": 6,
          "what": "Configure process management and monitoring",
          "why": "Ensure application restarts on crash",
          "when": "After initial deployment succeeds",
          "skip_if": "Orchestrator handles this",
          "how": "Use --restart=unless-stopped",
          "verify": "Kill the app process - it should restart",
          "success": true,
          "details": "using --restart=unless-stopped, verified restart after docker stop/start"
        }
      ]
    },
    {
      "path": "prod-cluster (Kubernetes)",
      "description": "Production Kubernetes cluster with HPA",
      "status": "complete",
      "step_count": 6,
      "steps": [
        {
          "order": 1,
          "what": "Assess deployment environment",
          "why": "Node.js apps can run in many ways",
          "when": "Before deployment",
          "how": "Evaluate options based on infrastructure",
          "verify": "Deployment method chosen",
          "success": true,
          "details": "chose Kubernetes for auto-scaling and zero-downtime deployments"
        },
        {
          "order": 2,
          "what": "Install Node.js runtime",
          "why": "Required for PM2 and systemd deployments",
          "when": "If using PM2 or systemd deployment",
          "skip_if": "Using Docker/K8s",
          "how": "Install via package manager",
          "verify": "node --version shows v20.x",
          "success": true,
          "details": "using Kubernetes, runtime in container image"
        },
        {
          "order": 3,
          "what": "Prepare application",
          "why": "Application needs dependencies and build artifacts",
          "when": "Before running the application",
          "skip_if": "Using pre-built container image",
          "how": "Build and push container image to registry",
          "verify": "Image in registry",
          "success": true,
          "details": "CI/CD builds image, pushed to registry.company.com/api:v1.2.3"
        },
        {
          "order": 4,
          "what": "Configure environment variables",
          "why": "12-factor app configuration",
          "when": "Before starting the application",
          "how": "Create ConfigMap and Secret in Kubernetes",
          "verify": "ConfigMap and Secret exist in namespace",
          "success": true,
          "details": "created api-config ConfigMap and api-secrets Secret in prod namespace"
        },
        {
          "order": 5,
          "what": "Deploy and start application",
          "why": "Run the application",
          "when": "After application is prepared",
          "how": "kubectl apply -f deployment.yaml",
          "verify": "curl http://api-service/health returns success",
          "success": true,
          "details": "deployed 3 replicas, rolling update completed, /health returning 200"
        },
        {
          "order": 6,
          "what": "Configure process management and monitoring",
          "why": "Ensure application restarts on crash",
          "when": "After initial deployment succeeds",
          "skip_if": "Orchestrator handles this",
          "how": "K8s has built-in restart policies",
          "verify": "Kill a pod - it should be recreated",
          "success": true,
          "details": "liveness/readiness probes configured, HPA scales 3-10 replicas based on CPU"
        }
      ]
    }
  ]
}
설치 위치: 3

설치 위치

dev-server (PM2) complete

Single development server using PM2 for process management

단계 수: 6
1 Assess deployment environment
이유
Node.js apps can run in many ways - choose what fits your infrastructure
시점
Before deployment
방법
Evaluate options: PM2, systemd, Docker, or Kubernetes
검증
Deployment method chosen based on infrastructure assessment
결과
chose PM2 for simplicity, already familiar with ecosystem.config.js
2 Install Node.js runtime
이유
Required for PM2 and systemd deployments
시점
If using PM2 or systemd deployment
건너뛰는 조건
Using Docker/K8s or Node.js already at required version
방법
Install via package manager or nvm
검증
node --version shows v20.x or higher
결과
nvm install 20 && nvm use 20, shows v20.10.0
3 Prepare application
이유
Application needs dependencies and build artifacts
시점
Before running the application
건너뛰는 조건
Using pre-built container image
방법
npm ci --production, then npm run build if needed
검증
node_modules exists, build artifacts present
결과
npm ci --production && npm run build, dist/ folder created
4 Configure environment variables
이유
12-factor app configuration via environment
시점
Before starting the application
방법
Set NODE_ENV=production, PORT, and app-specific config in ecosystem.config.js
검증
Environment variables accessible to application process
결과
added env section to ecosystem.config.js with NODE_ENV=production, PORT=3000
5 Deploy and start application
이유
Run the application with your chosen method
시점
After application is prepared
방법
pm2 start ecosystem.config.js && pm2 save
검증
curl http://localhost:3000/health returns success
결과
pm2 start ecosystem.config.js, /health returns {"status":"ok"}
6 Configure process management and monitoring
이유
Ensure application restarts on crash and is monitored
시점
After initial deployment succeeds
건너뛰는 조건
Orchestrator handles this
방법
Configure restart policies and monitoring
검증
Kill the app process - it should restart automatically
결과
pm2 startup configured, tested kill -9 and app restarted in 2s
staging-cluster (Docker) complete

Docker deployment on staging cluster

단계 수: 6
1 Assess deployment environment
이유
Node.js apps can run in many ways
시점
Before deployment
방법
Evaluate options based on infrastructure
검증
Deployment method chosen
결과
chose Docker for consistent environment with production
2 Install Node.js runtime
이유
Required for PM2 and systemd deployments
시점
If using PM2 or systemd deployment
건너뛰는 조건
Using Docker/K8s
방법
Install via package manager
검증
node --version shows v20.x
결과
using Docker, Node.js included in container image
3 Prepare application
이유
Application needs dependencies and build artifacts
시점
Before running the application
건너뛰는 조건
Using pre-built container image
방법
npm ci --production, npm run build
검증
Build artifacts present
결과
multi-stage Dockerfile builds image with npm ci && npm run build, final image 145MB
4 Configure environment variables
이유
12-factor app configuration
시점
Before starting the application
방법
Set environment variables via docker run -e or env_file
검증
Environment variables accessible
결과
created .env.staging with all config, using --env-file in docker run
5 Deploy and start application
이유
Run the application
시점
After application is prepared
방법
docker run -d --name myapp -p 3000:3000 myapp:latest
검증
curl http://localhost:3000/health returns success
결과
docker run -d --name api-staging -p 3000:3000 --env-file .env.staging myapp:v1.2.3
6 Configure process management and monitoring
이유
Ensure application restarts on crash
시점
After initial deployment succeeds
건너뛰는 조건
Orchestrator handles this
방법
Use --restart=unless-stopped
검증
Kill the app process - it should restart
결과
using --restart=unless-stopped, verified restart after docker stop/start
prod-cluster (Kubernetes) complete

Production Kubernetes cluster with HPA

단계 수: 6
1 Assess deployment environment
이유
Node.js apps can run in many ways
시점
Before deployment
방법
Evaluate options based on infrastructure
검증
Deployment method chosen
결과
chose Kubernetes for auto-scaling and zero-downtime deployments
2 Install Node.js runtime
이유
Required for PM2 and systemd deployments
시점
If using PM2 or systemd deployment
건너뛰는 조건
Using Docker/K8s
방법
Install via package manager
검증
node --version shows v20.x
결과
using Kubernetes, runtime in container image
3 Prepare application
이유
Application needs dependencies and build artifacts
시점
Before running the application
건너뛰는 조건
Using pre-built container image
방법
Build and push container image to registry
검증
Image in registry
결과
CI/CD builds image, pushed to registry.company.com/api:v1.2.3
4 Configure environment variables
이유
12-factor app configuration
시점
Before starting the application
방법
Create ConfigMap and Secret in Kubernetes
검증
ConfigMap and Secret exist in namespace
결과
created api-config ConfigMap and api-secrets Secret in prod namespace
5 Deploy and start application
이유
Run the application
시점
After application is prepared
방법
kubectl apply -f deployment.yaml
검증
curl http://api-service/health returns success
결과
deployed 3 replicas, rolling update completed, /health returning 200
6 Configure process management and monitoring
이유
Ensure application restarts on crash
시점
After initial deployment succeeds
건너뛰는 조건
Orchestrator handles this
방법
K8s has built-in restart policies
검증
Kill a pod - it should be recreated
결과
liveness/readiness probes configured, HPA scales 3-10 replicas based on CPU