Deploy Maillayer on any blank VPS using Node.js directly. No Docker required.
Prerequisites
- 2GB RAM minimum (4GB recommended)
- A domain name
- A Maillayer license with GitHub repo access
Step 1: Create a VPS
We recommend DigitalOcean for its simple interface. New accounts get $200 free credit for 60 days.
- Sign up at digitalocean.com
- Click Create → Droplets
- Choose Ubuntu 22.04 LTS
- Select Basic → Regular → $6/mo (1GB) or $12/mo (2GB recommended)
- Choose a datacenter region close to your users
- Set a root password or add your SSH key
- Click Create Droplet
- Copy your server's IP address once created
Alternative VPS Providers:
| Provider | Minimum Plan | Link |
|---|---|---|
| Hetzner | €3.79/mo (2GB) | hetzner.com |
| Vultr | $6/mo (1GB) | vultr.com |
| Linode | $5/mo (1GB) | linode.com |
Step 2: Point Domain to Your Server
Before starting, create a DNS A record pointing your domain to your VPS IP address.
- Log in to your domain registrar (Namecheap, Cloudflare, GoDaddy, etc.)
- Go to DNS settings
- Add an A Record:
- Name/Host:
mail(or@for root domain) - Value/Points to: Your VPS IP address (e.g.,
123.45.67.89) - TTL: Auto or 3600
- Name/Host:
- Save and wait 5-10 minutes for propagation
Verify DNS is working:
dig mail.yourdomain.com +short
Should return your VPS IP address.
Step 3: Connect to Your VPS
ssh root@your-server-ip
Step 4: Update System
apt update && apt upgrade -y
Step 5: Install Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
Verify:
node --version
npm --version
Step 6: Install Git and Build Tools
apt install -y git build-essential
Step 7: Configure Firewall
ufw allow 22
ufw allow 80
ufw allow 443
ufw enable
Step 8: Choose Your MongoDB Setup
Option A: MongoDB Atlas (Recommended)
MongoDB Atlas is a free managed database. Your data stays separate from your server, making backups and migrations easier.
Why Atlas?
- Free 512MB cluster (enough for most users)
- Automatic backups
- Easy scaling when needed
- Data survives server rebuilds
Setup Steps:
- Go to mongodb.com/atlas
- Create a free account
- Click Build a Database
- Select M0 FREE tier
- Choose a cloud provider and region close to your VPS
- Click Create Cluster
Configure Network Access:
- Go to Network Access in the sidebar
- Click Add IP Address
- Add your VPS IP address (or use 0.0.0.0/0 for any IP)
- Click Confirm
Create Database User:
- Go to Database Access
- Click Add New Database User
- Set username and password (save these!)
- Set privileges to Read and Write to Any Database
- Click Add User
Get Connection String:
- Go to Database → Click Connect
- Select Drivers
- Copy the connection string
- Replace
<password>with your database user password
Your connection string looks like:
mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/maillayer?retryWrites=true&w=majority
Option B: Install MongoDB on VPS
If you prefer keeping everything on one server:
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-7.0.list
apt update
apt install -y mongodb-org
systemctl start mongod
systemctl enable mongod
Your connection string:
mongodb://localhost:27017/maillayer
Note: Self-hosted MongoDB means you handle backups yourself.
Step 9: Install Redis
apt install -y redis-server
systemctl enable redis-server
systemctl start redis-server
Verify:
redis-cli ping
Should return PONG.
Step 10: Clone Maillayer Repository
cd /opt
git clone https://github.com/YOUR_USERNAME/maillayer.git
cd maillayer
Replace YOUR_USERNAME with your GitHub username.
Step 11: Install Dependencies
npm install
Step 12: Create Environment File
nano /opt/maillayer/.env
Add the following:
NODE_ENV=production
BASE_URL=https://mail.yourdomain.com
NEXTAUTH_SECRET=your-secret-key-min-32-chars
TRACKING_SECRET=another-random-secret
MONGODB_URI=your-mongodb-connection-string
REDIS_URL=redis://localhost:6379
Generate secure secrets:
openssl rand -base64 32
Save and exit (Ctrl+X, Y, Enter).
Step 13: Build Maillayer
npm run build
Step 14: Install PM2 (Process Manager)
PM2 keeps Maillayer running and restarts it if it crashes.
npm install -g pm2
Start Maillayer:
pm2 start npm --name "maillayer" -- start
Enable auto-start on boot:
pm2 startup
pm2 save
Check status:
pm2 status
pm2 logs maillayer
Step 15: Set Up SSL with Caddy
Install Caddy:
apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt update
apt install caddy
Configure Caddy:
nano /etc/caddy/Caddyfile
Add:
mail.yourdomain.com {
reverse_proxy localhost:3000
}
Restart Caddy:
systemctl restart caddy
SSL is now active automatically.
Step 16: Access Maillayer
Open https://mail.yourdomain.com in your browser and create your admin account.
Updating Maillayer
cd /opt/maillayer
git pull origin main
npm install
npm run build
pm2 restart maillayer
Backup MongoDB (Self-Hosted)
mongodump --out /opt/backups/$(date +%Y%m%d)
View Logs
pm2 logs maillayer
Restart Services
pm2 restart maillayer
systemctl restart redis-server
systemctl restart mongod # if self-hosted
Estimated Costs
| Resource | Cost |
|---|---|
| Hetzner CX21 (2GB) | €4.85/month |
| DigitalOcean (2GB) | $12/month |
| Vultr (2GB) | $10/month |
| MongoDB Atlas M0 | Free |
Total: ~$5-12/month
Troubleshooting
Maillayer not starting
pm2 logs maillayer
Check for missing environment variables or connection errors.
MongoDB Atlas connection refused
- Verify your VPS IP is whitelisted in Network Access
- Check your connection string password
- Ensure you're using the full connection string with
mongodb+srv://
Caddy not serving HTTPS
- Verify DNS A record points to your server
- Check Caddy logs:
journalctl -u caddy - Wait 2-3 minutes for certificate provisioning
Port 3000 not accessible
- Check if Maillayer is running:
pm2 status - Verify firewall:
ufw status
npm install fails
- Check Node.js version:
node --version(should be 20.x) - Clear npm cache:
npm cache clean --force
Out of memory during build Add swap space:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
