A lightweight, production-ready transactional email API built with Node.js, BullMQ, and Nodemailer. Perfect for sending emails with templates, retry logic, and queue management.
| Tag | Description | Platform |
|---|---|---|
latest | Latest stable release | Multi-platform |
v1.0.0 | Version 1.0.0 | Multi-platform |
v1.0.0-amd64 | AMD64 specific | Linux x86_64 |
v1.0.0-arm64 | ARM64 specific | Apple Silicon, ARM64 Linux |
Note: This example includes template volumes which are essential for using custom email templates.
services:
api:
image: himelranaswe/hs-mail-queue:latest
container_name: hs-mail-queue-api
ports:
- "3005:3000"
volumes:
- ./templates:/app/templates:ro
env_file:
- .env
environment:
NODE_ENV: ${NODE_ENV:-production}
restart: unless-stopped
worker:
image: himelranaswe/hs-mail-queue:latest
container_name: hs-mail-queue-worker
command: npm run worker
volumes:
- ./templates:/app/templates:ro
env_file:
- .env
environment:
NODE_ENV: ${NODE_ENV:-production}
restart: unless-stopped
# Server Configuration
PORT=3000
NODE_ENV=development
# Redis Configuration
REDIS_URL=your redis URL here
# SMTP Configuration
SMTP_HOST=smtp.yourdomain.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-smtp-username
SMTP_PASS=your-smtp-password
# Email Configuration
[email protected]
FROM_NAME=Your Service Name
# API Security
API_KEYS={"himosoft":"himosoft-strong-api-key","admin":"admin-secret-key","client":"client-api-key"}
# Queue Configuration
QUEUE_NAME=email-queue
MAX_RETRIES=3
RETRY_DELAY=5000
# Temp Email Detection
FAKE_EMAIL_FILTER=false
# MX Record Verification
ENABLE_MX_VERIFICATION=false
# Server Configuration
PORT=3000
NODE_ENV=development
# Redis Configuration
REDIS_URL=redis://redis:6379/3
# SMTP Configuration
SMTP_HOST=smtp.yourdomain.com
SMTP_PORT=587
SMTP_SECURE=false
[email protected]
SMTP_PASS=smtp_password
# Email Configuration
[email protected]
FROM_NAME=HIMOSOFT
# API Security
API_KEYS={"himosoft":"himosoft-strong-api-key","admin":"admin-secret-key","client":"client-api-key"}
# Queue Configuration
QUEUE_NAME=email-queue
MAX_RETRIES=3
RETRY_DELAY=5000
# Temp Email Detection
FAKE_EMAIL_FILTER=true
# MX Record Verification
ENABLE_MX_VERIFICATION=true
# 1. Create templates directory
mkdir -p templates
# 2. Create a sample template
cat > templates/welcome.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Welcome to {{companyName}}</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; }
.header { background-color: #007bff; color: white; padding: 20px; text-align: center; }
.content { padding: 30px; }
</style>
</head>
<body>
<div class="header">
<h1>Welcome to {{companyName}}!</h1>
</div>
<div class="content">
<h2>Hello {{userName}}!</h2>
<p>{{welcomeMessage}}</p>
</div>
</body>
</html>
EOF
# 3. Create .env file
cat > .env << EOF
SMTP_HOST=smtp.yourdomain.com
[email protected]
SMTP_PASS=your-password
[email protected]
FROM_NAME=Your Company
API_KEYS={"himosoft":"himosoft-strong-api-key","admin":"admin-secret-key","client":"client-api-key"}
EOF
# 4. Start the stack
docker-compose up -d
# 5. Copy templates to volume
docker run --rm -v "$(pwd)/templates:/source" -v hs-mail-queue_email_templates:/dest \
alpine cp -r /source/* /dest/
# 1. Create templates directory
mkdir -p templates
# 2. Create a sample template
cat > templates/welcome.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Welcome to {{companyName}}</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; }
.header { background-color: #007bff; color: white; padding: 20px; text-align: center; }
.content { padding: 30px; }
</style>
</head>
<body>
<div class="header">
<h1>Welcome to {{companyName}}!</h1>
</div>
<div class="content">
<h2>Hello {{userName}}!</h2>
<p>{{welcomeMessage}}</p>
</div>
</body>
</html>
EOF
# 3. Create .env file
cat > .env << EOF
SMTP_HOST=smtp.yourdomain.com
[email protected]
SMTP_PASS=your-password
[email protected]
FROM_NAME=Your Company
API_KEYS={"himosoft":"himosoft-strong-api-key","admin":"admin-secret-key","client":"client-api-key"}
EOF
# 4. Start the stack
docker-compose up -d
# 5. Copy templates to volume
docker run --rm -v "$(pwd)/templates:/source" -v hs-mail-queue_email_templates:/dest \
alpine cp -r /source/* /dest/
curl -X POST http://localhost:3000/api/send-email \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key" \
-d '{
"to": "[email protected]",
"subject": "Welcome!",
"templateName": "welcome",
"variables": {
"name": "John Doe",
"company": "HIMOSOFT"
}
}'
curl http://localhost:3000/api/health
curl -H "X-API-Key: your-secret-api-key" \
http://localhost:3000/api/queue-status
SMTP_HOST - SMTP server hostnameSMTP_USER - SMTP username/emailSMTP_PASS - SMTP passwordFROM_EMAIL - Sender email addressFROM_NAME - Sender nameAPI_KEYS - Multiple API keys with names (JSON format)NODE_ENV - Node.js environment (default: production)PORT - API server port (default: 3000)SMTP_PORT - SMTP server port (default: 587)SMTP_SECURE - Use TLS/SSL (default: false)REDIS_URL - Redis connection URL (default: redis://redis:6379)QUEUE_NAME - BullMQ queue name (default: email-queue)MAX_RETRIES - Maximum email retry attempts (default: 3)RETRY_DELAY - Retry delay in milliseconds (default: 5000)FAKE_EMAIL_FILTER - Enable disposable email filtering (default: true)ENABLE_MX_VERIFICATION - Enable MX record verification (default: false)Built-in protection against disposable/temporary email addresses using the FakeFilter API.
Configuration:
FAKE_EMAIL_FILTER=true # Enabled by default
How it works:
The worker validates that email domains have proper MX records before sending emails.
Configuration:
ENABLE_MX_VERIFICATION=true # Disabled by default
How it works:
Example logs:
š MX verification: ENABLED
š Checking MX records for domain: gmail.com
ā
MX records found for gmail.com: gmail-smtp-in.l.google.com (priority: 5), alt1.gmail-smtp-in.l.google.com (priority: 10)
ā
MX verification: All domains have valid MX records
When MX verification blocks an email:
ā Job 5 BLOCKED: No MX records for '[email protected]'
š§ Job details: {
jobId: '5',
to: '[email protected]',
subject: 'Test Email',
blockedAddress: '[email protected]'
}
ā Job 5 failed: Blocked email '[email protected]' - no MX records found
Benefits:
The image includes several HTML email templates:
welcome - Welcome email templatepassword-reset - Password reset templatenotification - General notification templatecurl -X POST http://localhost:3000/api/send-email \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key" \
-d '{
"to": "[email protected]",
"subject": "Password Reset",
"templateName": "password-reset",
"variables": {
"resetLink": "https://example.com/reset?token=abc123",
"expiresIn": "24 hours"
}
}'
Create your custom templates in a templates directory and mount them using Docker volumes:
services:
api:
image: himelranaswe/hs-mail-queue:latest
volumes:
- ./templates:/app/templates:ro # Bind mount for development
- email_templates:/app/templates:ro # Named volume for production
# ... other configuration
volumes:
email_templates:
driver: local
templates/
āāā welcome.html
āāā order-confirmation.html
āāā newsletter.html
āāā invoice.html
Create a file templates/welcome.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome to {{companyName}}</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
text-align: center;
}
.content {
padding: 30px;
}
.button {
display: inline-block;
background-color: #007bff;
color: white;
padding: 12px 24px;
text-decoration: none;
border-radius: 5px;
margin: 20px 0;
}
.footer {
background-color: #f8f9fa;
padding: 20px;
text-align: center;
color: #6c757d;
}
</style>
</head>
<body>
<div class="header">
<h1>Welcome to {{companyName}}!</h1>
<p>We're excited to have you on board</p>
</div>
<div class="content">
<h2>Hello {{userName}},</h2>
<p>Thank you for joining {{companyName}}! We're thrilled to have you as part of our community.</p>
{{#if welcomeMessage}}
<p>{{welcomeMessage}}</p>
{{/if}}
<h3>Getting Started</h3>
<ul>
{{#each gettingStartedSteps}}
<li>{{this}}</li>
{{/each}}
</ul>
{{#if verificationRequired}}
<p>Please verify your email address to get started:</p>
<a href="{{verificationUrl}}" class="button">Verify Email</a>
{{/if}}
{{#if dashboardUrl}}
<p>Ready to explore? Visit your dashboard:</p>
<a href="{{dashboardUrl}}" class="button">Go to Dashboard</a>
{{/if}}
<p>If you have any questions, feel free to reach out to our support team.</p>
<p>Best regards,<br>The {{companyName}} Team</p>
</div>
<div class="footer">
<p>Ā© {{currentYear}} {{companyName}}. All rights reserved.</p>
<p>Contact: {{contactEmail}} | Support: {{supportEmail}}</p>
{{#if unsubscribeUrl}}
<p><a href="{{unsubscribeUrl}}">Unsubscribe</a></p>
{{/if}}
</div>
</body>
</html>
Use Handlebars syntax for dynamic content:
| Variable Type | Syntax | Example |
|---|---|---|
| Simple | {{variableName}} | {{userName}}, {{companyName}} |
| Conditional | {{#if variable}}...{{/if}} | Show content only if variable exists |
| Loops | {{#each array}}...{{/each}} | Iterate through arrays |
| Nested | {{object.property}} | {{user.firstName}} |
curl -X POST http://localhost:3000/api/send-email \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key" \
-d '{
"to": "[email protected]",
"subject": "Welcome to HIMOSOFT!",
"templateName": "welcome",
"variables": {
"userName": "John Doe",
"companyName": "HIMOSOFT",
"welcomeMessage": "We are excited to have you join our platform!",
"gettingStartedSteps": [
"Complete your profile",
"Explore our features",
"Connect with others"
],
"verificationRequired": true,
"verificationUrl": "https://example.com/verify?token=abc123",
"dashboardUrl": "https://example.com/dashboard",
"currentYear": "2024",
"contactEmail": "[email protected]",
"supportEmail": "[email protected]"
}
}'
# List available templates
curl -H "X-API-Key: your-secret-api-key" \
http://localhost:3000/api/templates
# Copy templates to volume (after editing)
docker run --rm -v "$(pwd)/templates:/source" -v hs-mail-queue_email_templates:/dest \
alpine cp -r /source/* /dest/
# Restart containers to pick up changes
docker-compose restart api worker
GET /api/health - Basic health checkGET /api/health/queue - Queue health checkGET /api/queue-status - Queue statisticsGET /api/templates - Available templatesThis project is licensed under the MIT License - see the LICENSEā file for details.
Made with ā¤ļø by Himel
Content type
Image
Digest
sha256:c28245badā¦
Size
47.2 MB
Last updated
about 1 year ago
docker pull himelranaswe/hs-mail-queue