Skip to main content

Environment Variables

PMDaemon uses environment variables for system-level configuration and automatically injects process-specific variables into managed processes. This reference covers both PMDaemon's own environment variables and those it provides to your applications.

PMDaemon System Variables

These environment variables configure PMDaemon's behavior:

PMDAEMON_HOME

Description: Override the default configuration directory for PMDaemon Default: ~/.pmdaemon (Linux/macOS), %APPDATA%\pmdaemon (Windows) Example:

export PMDAEMON_HOME=/etc/pmdaemon
pmdaemon start "node server.js" --name web-api

This is the only environment variable that PMDaemon itself recognizes. All other configuration is done through CLI arguments or configuration files.

Process Variables

PMDaemon automatically sets environment variables for managed processes: pmdaemon start "node server.js" --name web-api # Max 5 restarts


## Process-Injected Variables

PMDaemon automatically injects these variables into managed processes:

### Core Process Variables

#### `PORT`
**Description:** Assigned port number for the process
**Set when:** Process has port configuration
**Example:**
```bash
pmdaemon start "node server.js" --name web-api --port 3000
# Process receives: PORT=3000

Application usage:

// Node.js
const port = process.env.PORT || 3000;
app.listen(port);
# Python
import os
port = int(os.environ.get('PORT', 8000))
app.run(port=port)

PM2_INSTANCE_ID

Description: Zero-based instance identifier for clustering Set when: Process runs in cluster mode (instances > 1) Example:

pmdaemon start "node server.js" --name web-cluster --instances 3 --port 3000-3002
# Instance 0: PM2_INSTANCE_ID=0, PORT=3000
# Instance 1: PM2_INSTANCE_ID=1, PORT=3001
# Instance 2: PM2_INSTANCE_ID=2, PORT=3002

Application usage:

// Node.js - Instance-specific behavior
const instanceId = parseInt(process.env.PM2_INSTANCE_ID || '0');
console.log(`Worker ${instanceId} starting...`);

// Instance-specific configuration
if (instanceId === 0) {
// Master instance - handle cron jobs
startCronJobs();
}

NODE_APP_INSTANCE

Description: Instance identifier for Node.js compatibility Set when: Process runs in cluster mode Value: Same as PM2_INSTANCE_ID Example:

pmdaemon start "node server.js" --name web-cluster --instances 2
# Instance 0: NODE_APP_INSTANCE=0
# Instance 1: NODE_APP_INSTANCE=1

Process Metadata Variables

PMDAEMON_PROCESS_NAME

Description: Process name as defined in PMDaemon Always set: Yes Example:

pmdaemon start "node server.js" --name web-api
# Process receives: PMDAEMON_PROCESS_NAME=web-api

PMDAEMON_PROCESS_ID

Description: PMDaemon internal process ID Always set: Yes Example:

# Process receives: PMDAEMON_PROCESS_ID=0

PMDAEMON_NAMESPACE

Description: Process namespace Set when: Namespace is specified Example:

pmdaemon start "node server.js" --name web-api --namespace production
# Process receives: PMDAEMON_NAMESPACE=production

PMDAEMON_VERSION

Description: PMDaemon version managing the process Always set: Yes Example:

# Process receives: PMDAEMON_VERSION=0.1.1

Custom Environment Variables

Setting via CLI

# Single variable
pmdaemon start "node server.js" --name web-api --env NODE_ENV=production

# Multiple variables
pmdaemon start "node server.js" --name web-api \
--env NODE_ENV=production \
--env DATABASE_URL=postgres://localhost/mydb \
--env API_KEY=secret123

Setting via Environment File

Create a .env file:

# .env.production
NODE_ENV=production
DATABASE_URL=postgres://localhost/mydb
API_KEY=secret123
PORT=3000
DEBUG=app:*

Use with PMDaemon:

pmdaemon start "node server.js" --name web-api --env-file .env.production

Setting via Configuration File

JSON format:

{
"name": "web-api",
"script": "node",
"args": ["server.js"],
"env": {
"NODE_ENV": "production",
"DATABASE_URL": "postgres://localhost/mydb",
"API_KEY": "secret123"
}
}

YAML format:

name: web-api
script: node
args: [server.js]
env:
NODE_ENV: production
DATABASE_URL: postgres://localhost/mydb
API_KEY: secret123

Environment Variable Precedence

When the same variable is defined in multiple places, PMDaemon uses this precedence:

  1. CLI --env flags (highest priority)
  2. Environment file (--env-file)
  3. Configuration file env section
  4. PMDaemon-injected variables
  5. Parent process environment (lowest priority)

Example:

# Parent process has NODE_ENV=development
# Configuration file has NODE_ENV=staging
# CLI override takes precedence
pmdaemon start "node server.js" --name web-api --env NODE_ENV=production
# Process receives: NODE_ENV=production

Environment Variable Patterns

Development vs Production

Development:

# .env.development
NODE_ENV=development
DEBUG=*
LOG_LEVEL=debug
DATABASE_URL=postgres://localhost/mydb_dev

Production:

# .env.production
NODE_ENV=production
DEBUG=app:error
LOG_LEVEL=info
DATABASE_URL=postgres://prod-server/mydb

Instance-Specific Configuration

// Node.js - Different behavior per instance
const instanceId = parseInt(process.env.PM2_INSTANCE_ID || '0');

// Instance 0 handles background tasks
if (instanceId === 0) {
require('./background-tasks');
}

// All instances handle web requests
require('./web-server');

Database Connection Pooling

// Node.js - Scale connection pool with instances
const instanceId = parseInt(process.env.PM2_INSTANCE_ID || '0');
// Total instances can be tracked in your application logic
// Total instances can be tracked in your application logic
const totalInstances = process.env.INSTANCES || 1;

const poolSize = Math.ceil(100 / totalInstances); // Distribute 100 connections
const dbConfig = {
host: process.env.DATABASE_HOST,
database: process.env.DATABASE_NAME,
pool: {
min: 1,
max: poolSize
}
};

Security Considerations

Sensitive Variables

# Good: Use environment files for secrets
echo "API_KEY=secret123" > .env.production
chmod 600 .env.production
pmdaemon start "node api.js" --name api --env-file .env.production

# Avoid: Secrets in CLI (visible in process list)
pmdaemon start "node api.js" --name api --env API_KEY=secret123

Variable Validation

// Node.js - Validate required environment variables
const requiredVars = ['DATABASE_URL', 'API_KEY', 'JWT_SECRET'];
const missing = requiredVars.filter(varName => !process.env[varName]);

if (missing.length > 0) {
console.error(`Missing required environment variables: ${missing.join(', ')}`);
process.exit(1);
}

Environment Isolation

# Use namespaces to isolate environments
pmdaemon start "node api.js" --name api --namespace production --env-file .env.prod
pmdaemon start "node api.js" --name api --namespace staging --env-file .env.staging

Debugging Environment Variables

View Process Environment

# View all environment variables for a process
pmdaemon info web-api

# View specific process details
pmdaemon describe web-api

Log Environment Variables

// Node.js - Log environment on startup
console.log('Environment variables:');
console.log('NODE_ENV:', process.env.NODE_ENV);
console.log('PORT:', process.env.PORT);
console.log('PM2_INSTANCE_ID:', process.env.PM2_INSTANCE_ID);
console.log('PMDAEMON_PROCESS_NAME:', process.env.PMDAEMON_PROCESS_NAME);

Environment Variable Conflicts

# Check for conflicts
env | grep NODE_ENV # Check system environment
pmdaemon info web-api | grep -A 20 "Environment" # Check process environment

Best Practices

1. Use Environment Files

# Good: Organized environment files
pmdaemon start "node api.js" --name api --env-file .env.production

# Avoid: Long CLI commands
pmdaemon start "node api.js" --name api --env VAR1=value1 --env VAR2=value2 --env VAR3=value3

2. Validate Required Variables

// Good: Validate on startup
const config = {
port: process.env.PORT || 3000,
dbUrl: process.env.DATABASE_URL || (() => {
throw new Error('DATABASE_URL is required');
})(),
apiKey: process.env.API_KEY || (() => {
throw new Error('API_KEY is required');
})()
};

3. Use Instance-Specific Logic

// Good: Instance-aware code
const instanceId = parseInt(process.env.PM2_INSTANCE_ID || '0');

// Only instance 0 runs scheduled tasks
if (instanceId === 0) {
startScheduledTasks();
}

4. Secure Sensitive Data

# Good: Secure file permissions
chmod 600 .env.production
pmdaemon start "node api.js" --name api --env-file .env.production

# Good: Use external secret management
pmdaemon start "node api.js" --name api --env DATABASE_URL="$(vault kv get -field=url secret/db)"

Next Steps