nodejs-app
Deploy a Node.js application - supports PM2, systemd, Docker, or Kubernetes
Recipaie - Deployment Recipe
The template that describes how to deploy this service.
Raw 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
}
Prerequisites
Node.js 18+ runtime (unless using containerized deployment)Application source code or container imageOne of: PM2 process manager, systemd, Docker, or Kubernetes
Steps
1 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
2 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
3 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
4 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
5 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
6 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
Prodaie - Execution Record
What happened when an AI executed this recipe in different environments.
Raw 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"
}
]
}
]
}
Locations
dev-server (PM2) complete
Single development server using PM2 for process management
1 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
- Result
- ✓ chose PM2 for simplicity, already familiar with ecosystem.config.js
2 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
- Result
- ✓ nvm install 20 && nvm use 20, shows v20.10.0
3 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
- Result
- ✓ npm ci --production && npm run build, dist/ folder created
4 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
- Result
- ✓ added env section to ecosystem.config.js with NODE_ENV=production, PORT=3000
5 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
- Result
- ✓ pm2 start ecosystem.config.js, /health returns {"status":"ok"}
6 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
- Result
- ✓ pm2 startup configured, tested kill -9 and app restarted in 2s
staging-cluster (Docker) complete
Docker deployment on staging cluster
1 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
- Result
- ✓ chose Docker for consistent environment with production
2 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
- Result
- ✓ using Docker, Node.js included in container image
3 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
- Result
- ✓ multi-stage Dockerfile builds image with npm ci && npm run build, final image 145MB
4 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
- Result
- ✓ created .env.staging with all config, using --env-file in docker run
5 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
- Result
- ✓ docker run -d --name api-staging -p 3000:3000 --env-file .env.staging myapp:v1.2.3
6 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
- Result
- ✓ using --restart=unless-stopped, verified restart after docker stop/start
prod-cluster (Kubernetes) complete
Production Kubernetes cluster with HPA
1 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
- Result
- ✓ chose Kubernetes for auto-scaling and zero-downtime deployments
2 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
- Result
- ✓ using Kubernetes, runtime in container image
3 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
- Result
- ✓ CI/CD builds image, pushed to registry.company.com/api:v1.2.3
4 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
- Result
- ✓ created api-config ConfigMap and api-secrets Secret in prod namespace
5 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
- Result
- ✓ deployed 3 replicas, rolling update completed, /health returning 200
6 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
- Result
- ✓ liveness/readiness probes configured, HPA scales 3-10 replicas based on CPU