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