Installation
Deploying EXMER itself — the Express backend and React Mini App — on your own server. Takes about fifteen minutes on a fresh Linux VM.
Requirements
- Linux server (Debian, Ubuntu, RHEL, Fedora, Alpine, or Arch)
- Node.js 22+ and npm
- Caddy 2.x (for automatic HTTPS)
- A domain name pointed at the server's IP
- A Telegram bot token from @BotFather
- Optional: an Anthropic API key for AI Analysis
1. Clone and build
git clone https://github.com/exmedev/exmer.git /opt/exmer
cd /opt/exmer
cd backend && npm install && npm run build && cd ..
cd frontend && npm install && npm run build && cd ..
The backend compiles TypeScript to backend/dist/. The frontend builds static assets into frontend/dist/, which the backend serves at any non-API path.
2. Configure environment
cd /opt/exmer/backend
cp .env.example .env
Edit .env to set:
JWT_SECRET— generate withnode -e "console.log(require('crypto').randomBytes(32).toString('hex'))". Required; refuses to start without it.TELEGRAM_BOT_TOKEN— from BotFather.ADMIN_USER_IDS— comma-separated Telegram user IDs of super-admins.APP_DOMAIN— your domain, e.g.exer.me.ANTHROPIC_API_KEY— optional, enables AI Analysis.AI_MODEL— optional, e.g.claude-sonnet-4-20250514.LOG_LEVEL— optional, one ofdebug,info,warn,error. Default:info.
.env to git. The .gitignore already excludes it, but double-check. JWT_SECRET is used to derive the database encryption key — if it leaks, every stored SSH credential can be decrypted.
3. systemd service
Create /etc/systemd/system/exmer.service:
[Unit]
Description=EXMER backend
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/exmer/backend
EnvironmentFile=/opt/exmer/backend/.env
ExecStart=/usr/bin/node dist/index.js
Restart=on-failure
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now exmer
systemctl status exmer
4. Caddy reverse proxy
Create /etc/caddy/Caddyfile:
exer.me {
encode gzip
reverse_proxy localhost:3000
}
Reload Caddy: systemctl reload caddy. It automatically provisions a Let's Encrypt cert.
5. Wire the bot to BotFather
Open @BotFather, run /mybots, select your bot, then Bot Settings → Menu Button → Configure menu button. Enter:
- URL:
https://exer.me - Text:
Open EXMER
6. Verify
curl https://exer.me/api/health
Should return {"status":"ok","name":"EXMER","version":"1.0.0", ...}. If yes, you're done.
Database backups
EXMER runs an automatic daily backup of data/exmer.db into data/backups/ with 30-day retention. The first backup fires 60 seconds after startup. Super-admins can trigger manual backups and download them via the admin panel. See Security for details.