Installing EmailEngine from Source
Complete guide for running EmailEngine from source code - the recommended method for production deployments.
Why Install from Source?
Running EmailEngine from source provides several advantages over binary distributions:
Production Benefits
Lower Memory Usage: The pre-built binary uses a virtual filesystem where all application files are loaded into memory at startup. When running from source, files remain on disk and are only loaded when needed, resulting in lower base memory consumption.
Better Performance:
- Native Node.js execution without packaging overhead
- Faster startup times
- More efficient resource utilization
Enhanced Control:
- Full access to source code for debugging
- Ability to apply custom patches if needed
- Direct configuration without binary limitations
- Easier integration with monitoring tools
Production Recommendation: For production environments, especially those managing many email accounts or running on resource-constrained servers, source installation is the recommended approach.
System Requirements
Minimum (development/testing):
- 1-2 CPU cores
- 2 GB RAM
- 10 GB storage
Recommended (production):
- 4+ CPU cores
- 4-8 GB RAM or more
- 20+ GB SSD storage
Required Software
- Node.js 20+ (24+ recommended for best performance)
- Redis 6.0+ (stand-alone mode, persistence enabled)
- wget/curl (for downloading release tarballs)
Privileges
EmailEngine does not require root or administrator privileges to run. You can run it as any unprivileged user (e.g., a dedicated emailengine user) on any unprivileged port (e.g., 3000).
Root access is only needed during initial setup to:
- Create directories in
/optand set ownership - Create the SystemD service file or Launch Agent
- Create a dedicated system user
- Bind the SMTP or IMAP proxy to privileged ports (below 1024, such as 465 or 993)
Once installed, EmailEngine runs as an unprivileged user. For privileged ports, instead of running as root, consider these safer alternatives:
- Use a reverse proxy (Nginx, Caddy) to forward traffic
- Use
setcapto grant port binding capabilities:sudo setcap 'cap_net_bind_service=+ep' $(which node) - Use iptables/nftables to redirect ports
Installation Methods
Choose between stable releases or development versions:
- Release Tarball (recommended for production) - Stable, tested releases
- Git Repository (for development) - Latest features, may be unstable
Method 1: Release Tarball (Recommended)
Linux Installation
Prerequisites
Before installing EmailEngine from source, you need Node.js 20+ (24+ recommended) and Redis 6.0+:
- Node.js & Redis setup: Follow Steps 1-2 in the Linux Installation Guide
- Returns to this guide after completing the prerequisites
Step 1: Setup Directory Structure
# Create directories
sudo mkdir -p /opt/emailengine/app
cd /opt/emailengine
Step 2: Configure Environment
Create and populate .env file in /opt/emailengine:
# Generate encryption secret and create .env file
sudo bash -c "cat > /opt/emailengine/.env" <<EOF
# Redis connection (database 8 is the default)
EENGINE_REDIS=redis://127.0.0.1:6379/8
# Security secret (auto-generated)
EENGINE_SECRET=$(openssl rand -hex 32)
# Performance
EENGINE_WORKERS=4
# Logging
EENGINE_LOG_LEVEL=info
# API settings
EENGINE_PORT=3000
EENGINE_HOST=0.0.0.0
EOF
# Secure the file
sudo chmod 600 /opt/emailengine/.env
Important: The .env file is stored outside the app/ directory, making upgrades easier. Keep this file safe.
Step 3: Download and Install EmailEngine
cd /opt/emailengine
# Download latest source distribution
sudo wget https://go.emailengine.app/source-dist.tar.gz
# Or download specific version (e.g., 2.55.4)
sudo wget https://go.emailengine.app/download/v2.55.4/source-dist.tar.gz
# Extract to app directory (includes node_modules)
sudo tar xzf source-dist.tar.gz -C app --strip-components=1
sudo rm source-dist.tar.gz
The source-dist.tar.gz includes a complete node_modules folder with all production dependencies, so you don't need to run npm install.
Step 4: Test Installation
cd /opt/emailengine
node app/server.js
In another terminal:
curl http://localhost:3000/health
# Should return: {"success":true}
Press Ctrl+C to stop.
Step 5: Create System User
# Create dedicated user
sudo useradd --system --home /opt/emailengine --shell /bin/false emailengine
# Set ownership
sudo chown -R emailengine:emailengine /opt/emailengine
sudo chmod 600 /opt/emailengine/.env
Step 6: Set Up SystemD Service
Create service file:
sudo nano /etc/systemd/system/emailengine.service
Add configuration:
[Unit]
Description=EmailEngine Email API Service
Documentation=https://emailengine.app
After=network.target redis.service
Requires=redis.service
[Service]
Type=simple
User=emailengine
Group=emailengine
WorkingDirectory=/opt/emailengine
# Load environment variables
EnvironmentFile=/opt/emailengine/.env
# Start command
ExecStart=/usr/bin/node app/server.js
# Restart policy
Restart=always
RestartSec=10
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=emailengine
# Resource limits
LimitNOFILE=65536
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/emailengine
[Install]
WantedBy=multi-user.target
Enable and start service:
sudo systemctl daemon-reload
sudo systemctl enable emailengine
sudo systemctl start emailengine
sudo systemctl status emailengine
View logs:
sudo journalctl -u emailengine -f
macOS Installation
Prerequisites
Before installing EmailEngine from source, you need Node.js 20+ (24+ recommended) and Redis:
- Node.js & Redis setup: Follow Steps 1-2 in the macOS Installation Guide
- Returns to this guide after completing the prerequisites
Step 1: Download and Install EmailEngine
# Create directory structure
sudo mkdir -p /opt/emailengine/app
cd /opt/emailengine
# Download source (includes node_modules)
sudo curl -L https://go.emailengine.app/source-dist.tar.gz | sudo tar xz -C app --strip-components=1
Step 2: Configure Environment
Create /opt/emailengine/.env:
# Generate encryption secret and create .env file
sudo bash -c "cat > /opt/emailengine/.env" <<EOF
EENGINE_REDIS=redis://127.0.0.1:6379/8
EENGINE_SECRET=$(openssl rand -hex 32)
EENGINE_WORKERS=4
EENGINE_PORT=3000
EENGINE_HOST=0.0.0.0
EENGINE_LOG_LEVEL=info
EOF
# Secure the file
sudo chmod 600 /opt/emailengine/.env
Step 3: Run as Launch Agent
Create ~/Library/LaunchAgents/com.emailengine.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.emailengine</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>/opt/emailengine/app/server.js</string>
</array>
<key>WorkingDirectory</key>
<string>/opt/emailengine</string>
<key>EnvironmentVariables</key>
<dict>
<key>NODE_ENV</key>
<string>production</string>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/usr/local/var/log/emailengine.log</string>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/emailengine.error.log</string>
</dict>
</plist>
Load and start:
launchctl load ~/Library/LaunchAgents/com.emailengine.plist
Windows Installation
For Windows, use WSL2 (Windows Subsystem for Linux) and follow the Linux installation steps above.
See Windows Installation Guide for WSL2 setup.
Alternative Process Managers
PM2 (Production Process Manager)
PM2 is an excellent alternative to SystemD for process management.
Install PM2
sudo npm install -g pm2
Create PM2 Ecosystem File
Create /opt/emailengine/ecosystem.config.js:
module.exports = {
apps: [{
name: 'emailengine',
script: './app/server.js',
cwd: '/opt/emailengine',
instances: 1,
exec_mode: 'cluster',
watch: false,
env: {
NODE_ENV: 'production'
},
error_file: '/var/log/emailengine/error.log',
out_file: '/var/log/emailengine/out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true,
autorestart: true,
max_restarts: 10,
min_uptime: '10s'
}]
};
Note: Environment variables are loaded from /opt/emailengine/.env automatically.
Start with PM2
# Start EmailEngine
pm2 start ecosystem.config.js
# Save PM2 configuration
pm2 save
# Setup PM2 to start on boot
pm2 startup
# View logs
pm2 logs emailengine
# Monitor
pm2 monit
# Restart
pm2 restart emailengine
# Stop
pm2 stop emailengine
Docker with Source
If you want to build your own Docker image from source, the EmailEngine repository includes a production-ready Dockerfile. Clone the repository and build:
# Clone the repository
git clone https://github.com/postalsys/emailengine.git
cd emailengine
# Build the Docker image
docker build -t emailengine:custom .
# Run with Redis
docker run -d \
--name emailengine \
-p 3000:3000 \
-e EENGINE_REDIS="redis://redis-host:6379" \
-e EENGINE_SECRET="your-secret-key" \
emailengine:custom
The official Dockerfile includes security best practices like running as a non-root user and using dumb-init for proper signal handling.
Upgrading
The directory structure makes upgrades simple - just replace the app/ directory while keeping your .env file intact.
cd /opt/emailengine
# Stop service
sudo systemctl stop emailengine
# Backup current version (optional)
sudo mv app app.backup.$(date +%Y%m%d)
# Create new app directory
sudo mkdir -p app
# Download new version (latest)
sudo wget https://go.emailengine.app/source-dist.tar.gz
# Or download specific version (e.g., 2.55.4)
sudo wget https://go.emailengine.app/download/v2.55.4/source-dist.tar.gz
# Extract to app directory
sudo tar xzf source-dist.tar.gz -C app --strip-components=1
sudo rm source-dist.tar.gz
# Restore ownership
sudo chown -R emailengine:emailengine /opt/emailengine
# Start service
sudo systemctl start emailengine
# Verify
sudo systemctl status emailengine
curl http://localhost:3000/health
Note: Your .env file in /opt/emailengine/ is preserved during upgrades.
With PM2
The PM2 upgrade process is the same as SystemD - just replace the app/ directory and reload PM2.
cd /opt/emailengine
# Backup current version (optional)
sudo mv app app.backup.$(date +%Y%m%d)
# Create new app directory
sudo mkdir -p app
# Download new version (latest)
sudo wget https://go.emailengine.app/source-dist.tar.gz
# Or download specific version (e.g., 2.55.4)
sudo wget https://go.emailengine.app/download/v2.55.4/source-dist.tar.gz
# Extract to app directory
sudo tar xzf source-dist.tar.gz -C app --strip-components=1
sudo rm source-dist.tar.gz
# Reload with zero-downtime
pm2 reload emailengine
Configuration Options
Environment Variables
All configuration can be set via environment variables in .env file:
# Core settings
EENGINE_REDIS=redis://127.0.0.1:6379/8
EENGINE_SECRET=your-encryption-secret-at-least-32-chars
# Performance
EENGINE_WORKERS=4
# API
EENGINE_PORT=3000
EENGINE_HOST=0.0.0.0
# Logging
EENGINE_LOG_LEVEL=info
EENGINE_LOG_RAW=false
# Features (5MB = 5 * 1024 * 1024)
EENGINE_MAX_SIZE=5242880
See Configuration Options for complete reference.
Performance Optimization
Node.js Optimization
# Set Node.js options in SystemD service
Environment="NODE_OPTIONS=--max-old-space-size=2048"
# Or in ecosystem.config.js for PM2
node_args: '--max-old-space-size=2048'
Worker Configuration
# Set workers to CPU core count
EENGINE_WORKERS=4
# For high-load servers
EENGINE_WORKERS=8
Redis Optimization
See Linux Installation - Performance Tuning for Redis optimization.
Monitoring
Health Checks
# HTTP health endpoint
curl http://localhost:3000/health
# Returns: {"success":true}
Prometheus Metrics
Create a token with metrics scope:
emailengine tokens issue -d "Prometheus" -s "metrics"
Access metrics at /metrics endpoint:
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/metrics
Logs
# SystemD logs
sudo journalctl -u emailengine -f
# PM2 logs
pm2 logs emailengine
# Log files
tail -f /var/log/emailengine/*.log
Security Best Practices
- Run as dedicated user (not root)
- Secure
.envfile withchmod 600 - Use strong secrets (32+ characters)
- Enable firewall and restrict port access
- Use reverse proxy with TLS/HTTPS
- Keep Node.js updated to latest LTS version
- Regular backups of Redis data
- Monitor logs for suspicious activity
See Security Best Practices for detailed guidance.