0
# Docker Integration
1
2
PM2 Docker integration for containerized Node.js applications. Provides container-optimized runtime modes, Dockerfile generation, and production-ready containerization features with proper signal handling and graceful shutdowns.
3
4
## Capabilities
5
6
### Container Runtime Modes
7
8
PM2 provides specialized binaries for Docker container environments.
9
10
```bash { .api }
11
# PM2 Runtime - Optimized for Docker containers
12
pm2-runtime <script|config> [options]
13
14
# PM2 Docker - Alternative container binary
15
pm2-docker <script|config> [options]
16
17
# Production container startup
18
pm2-runtime start ecosystem.config.js --env production
19
20
# Single process container
21
pm2-runtime app.js --name "web-app"
22
23
# Cluster mode in container
24
pm2-runtime app.js -i max --name "api-cluster"
25
```
26
27
**Key Features:**
28
- Proper PID 1 signal handling
29
- Graceful container shutdown
30
- Log forwarding to stdout/stderr
31
- No daemon mode (foreground execution)
32
- Container health check support
33
34
### Dockerfile Generation
35
36
Generate optimized Dockerfiles for PM2 applications.
37
38
```javascript { .api }
39
/**
40
* Generate Dockerfile for PM2 application
41
* @param script - Application script path
42
* @param options - Docker configuration options
43
* @returns Generated Dockerfile content
44
*/
45
function generateDockerfile(script: string, options?: DockerOptions): string;
46
47
/**
48
* Configure Docker mode for application
49
* @param script - Application script path
50
* @param options - Docker configuration options
51
* @param mode - Docker execution mode
52
* @returns Docker configuration
53
*/
54
function dockerMode(script: string, options?: DockerOptions, mode?: string): any;
55
```
56
57
**Usage Examples:**
58
59
```javascript
60
const pm2 = require('pm2');
61
62
// Generate Dockerfile
63
const dockerfile = pm2.generateDockerfile('app.js', {
64
nodeVersion: '18-alpine',
65
imageName: 'my-app',
66
fresh: true
67
});
68
69
console.log(dockerfile);
70
// Outputs complete Dockerfile content
71
72
// Configure Docker mode
73
const dockerConfig = pm2.dockerMode('app.js', {
74
nodeVersion: '18',
75
dockerdaemon: false
76
}, 'production');
77
```
78
79
### Container Configuration
80
81
Configure PM2 applications for optimal container performance.
82
83
```javascript
84
// ecosystem.config.js for Docker
85
module.exports = {
86
apps: [{
87
name: 'web-app',
88
script: 'app.js',
89
90
// Container-specific settings
91
container: true,
92
kill_timeout: 5000,
93
shutdown_with_message: true,
94
95
// Environment configuration
96
env: {
97
NODE_ENV: 'production',
98
PORT: 3000
99
},
100
101
// Cluster mode in container
102
instances: 'max',
103
exec_mode: 'cluster',
104
105
// Log configuration for containers
106
merge_logs: true,
107
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
108
109
// Container health and restart settings
110
max_memory_restart: '1G',
111
max_restarts: 3,
112
min_uptime: '10s'
113
}]
114
};
115
```
116
117
## Docker Examples
118
119
### Basic Dockerfile with PM2
120
121
```dockerfile
122
FROM node:18-alpine
123
124
# Install PM2 globally
125
RUN npm install -g pm2
126
127
# Create app directory
128
WORKDIR /usr/src/app
129
130
# Copy package files
131
COPY package*.json ./
132
133
# Install dependencies
134
RUN npm ci --only=production
135
136
# Copy application code
137
COPY . .
138
139
# Expose port
140
EXPOSE 3000
141
142
# Use PM2 runtime for container
143
CMD ["pm2-runtime", "start", "ecosystem.config.js", "--env", "production"]
144
```
145
146
### Multi-stage Dockerfile
147
148
```dockerfile
149
# Build stage
150
FROM node:18-alpine AS builder
151
152
WORKDIR /usr/src/app
153
COPY package*.json ./
154
RUN npm ci --only=production
155
156
# Production stage
157
FROM node:18-alpine AS production
158
159
# Install PM2
160
RUN npm install -g pm2
161
162
# Create non-root user
163
RUN addgroup -g 1001 -S nodejs && \
164
adduser -S nodejs -u 1001
165
166
WORKDIR /usr/src/app
167
168
# Copy dependencies from builder
169
COPY --from=builder /usr/src/app/node_modules ./node_modules
170
COPY --chown=nodejs:nodejs . .
171
172
USER nodejs
173
174
EXPOSE 3000
175
176
# Health check
177
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
178
CMD pm2 ping || exit 1
179
180
CMD ["pm2-runtime", "start", "ecosystem.config.js", "--env", "production"]
181
```
182
183
### Docker Compose Integration
184
185
```yaml
186
# docker-compose.yml
187
version: '3.8'
188
189
services:
190
app:
191
build: .
192
container_name: my-pm2-app
193
ports:
194
- "3000:3000"
195
environment:
196
- NODE_ENV=production
197
- PM2_PUBLIC_KEY=${PM2_PUBLIC_KEY}
198
- PM2_SECRET_KEY=${PM2_SECRET_KEY}
199
volumes:
200
- ./logs:/usr/src/app/logs
201
restart: unless-stopped
202
healthcheck:
203
test: ["CMD", "pm2", "ping"]
204
interval: 30s
205
timeout: 10s
206
retries: 3
207
start_period: 40s
208
209
nginx:
210
image: nginx:alpine
211
ports:
212
- "80:80"
213
depends_on:
214
- app
215
volumes:
216
- ./nginx.conf:/etc/nginx/nginx.conf
217
```
218
219
### Container-Optimized Ecosystem File
220
221
```javascript
222
// ecosystem.config.js for containers
223
module.exports = {
224
apps: [{
225
name: 'api-server',
226
script: 'server.js',
227
228
// Container optimizations
229
container: true,
230
kill_timeout: 5000,
231
shutdown_with_message: true,
232
wait_ready: true,
233
listen_timeout: 10000,
234
235
// Instance configuration
236
instances: process.env.WEB_CONCURRENCY || 1,
237
exec_mode: 'cluster',
238
239
// Memory and restart settings
240
max_memory_restart: process.env.WEB_MEMORY || '512M',
241
max_restarts: 3,
242
min_uptime: '10s',
243
244
// Environment variables
245
env: {
246
NODE_ENV: 'production',
247
PORT: process.env.PORT || 3000
248
},
249
250
// Logging for containers
251
merge_logs: true,
252
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
253
254
// Error handling
255
autorestart: true,
256
watch: false,
257
258
// Source map support
259
source_map_support: true
260
}]
261
};
262
```
263
264
## Container Best Practices
265
266
### 1. Signal Handling
267
268
```javascript
269
// app.js - Proper signal handling in containers
270
process.on('SIGTERM', () => {
271
console.log('SIGTERM received, shutting down gracefully');
272
server.close(() => {
273
console.log('Process terminated');
274
process.exit(0);
275
});
276
});
277
278
process.on('SIGINT', () => {
279
console.log('SIGINT received, shutting down gracefully');
280
server.close(() => {
281
process.exit(0);
282
});
283
});
284
285
// Send ready signal to PM2 when app is ready
286
if (process.send) {
287
process.send('ready');
288
}
289
```
290
291
### 2. Health Checks
292
293
```javascript
294
// health-check.js
295
const http = require('http');
296
297
const options = {
298
hostname: 'localhost',
299
port: process.env.PORT || 3000,
300
path: '/health',
301
timeout: 2000
302
};
303
304
const req = http.request(options, (res) => {
305
if (res.statusCode === 200) {
306
process.exit(0);
307
} else {
308
process.exit(1);
309
}
310
});
311
312
req.on('error', () => {
313
process.exit(1);
314
});
315
316
req.end();
317
```
318
319
### 3. Log Management
320
321
```javascript
322
// ecosystem.config.js - Container logging
323
module.exports = {
324
apps: [{
325
name: 'app',
326
script: 'app.js',
327
328
// Forward logs to stdout/stderr for Docker
329
log_file: '/dev/null',
330
out_file: '/dev/stdout',
331
error_file: '/dev/stderr',
332
333
// Merge cluster logs
334
merge_logs: true,
335
336
// Log formatting
337
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
338
time: true
339
}]
340
};
341
```
342
343
### 4. Resource Limits
344
345
```javascript
346
// Resource-aware container configuration
347
module.exports = {
348
apps: [{
349
name: 'app',
350
script: 'app.js',
351
352
// Scale based on container resources
353
instances: process.env.WEB_CONCURRENCY || Math.max(1, require('os').cpus().length - 1),
354
355
// Memory limits based on container
356
max_memory_restart: process.env.WEB_MEMORY || '512M',
357
358
// Container-specific settings
359
container: true,
360
kill_timeout: parseInt(process.env.KILL_TIMEOUT) || 5000,
361
362
env: {
363
NODE_ENV: 'production',
364
UV_THREADPOOL_SIZE: process.env.UV_THREADPOOL_SIZE || 4
365
}
366
}]
367
};
368
```
369
370
## Container Deployment Patterns
371
372
### 1. Single Container Pattern
373
374
```dockerfile
375
FROM node:18-alpine
376
RUN npm install -g pm2
377
WORKDIR /app
378
COPY package*.json ./
379
RUN npm ci --only=production
380
COPY . .
381
EXPOSE 3000
382
CMD ["pm2-runtime", "app.js", "--name", "web-app", "-i", "max"]
383
```
384
385
### 2. Multi-Container Pattern
386
387
```yaml
388
# docker-compose.yml
389
version: '3.8'
390
services:
391
web:
392
build: .
393
environment:
394
- NODE_ENV=production
395
deploy:
396
replicas: 3
397
398
worker:
399
build: .
400
command: ["pm2-runtime", "worker.js", "--name", "background-worker"]
401
environment:
402
- NODE_ENV=production
403
```
404
405
### 3. Microservices Pattern
406
407
```yaml
408
version: '3.8'
409
services:
410
auth-service:
411
build: ./services/auth
412
command: ["pm2-runtime", "start", "ecosystem.config.js"]
413
414
api-service:
415
build: ./services/api
416
command: ["pm2-runtime", "start", "ecosystem.config.js"]
417
depends_on:
418
- auth-service
419
```
420
421
## Core Types
422
423
```javascript { .api }
424
interface DockerOptions {
425
/** Docker image name */
426
imageName?: string;
427
/** Node.js version to use */
428
nodeVersion?: string;
429
/** Perform fresh installation */
430
fresh?: boolean;
431
/** Force Docker operations */
432
force?: boolean;
433
/** Docker daemon mode */
434
dockerdaemon?: boolean;
435
}
436
437
interface ContainerConfig {
438
/** Enable container mode */
439
container?: boolean;
440
/** Timeout for graceful shutdown */
441
kill_timeout?: number;
442
/** Use message-based shutdown */
443
shutdown_with_message?: boolean;
444
/** Wait for ready signal */
445
wait_ready?: boolean;
446
/** Timeout for listening */
447
listen_timeout?: number;
448
}
449
```
450
451
## CLI Container Commands
452
453
```bash { .api }
454
# Start with PM2 runtime (recommended for containers)
455
pm2-runtime start app.js
456
457
# Start ecosystem file in container
458
pm2-runtime start ecosystem.config.js --env production
459
460
# Start with specific options
461
pm2-runtime start app.js --name web-app -i max --kill-timeout 5000
462
463
# Generate Dockerfile
464
pm2 ecosystem --dockerfile
465
466
# Container health check
467
pm2 ping
468
```