MeshMonitor Proxmox LXC Deployment Guide β
This guide covers deploying MeshMonitor in a Proxmox VE LXC container using our pre-built templates.
Table of Contents β
- Overview
- Prerequisites
- Quick Start
- Detailed Installation
- Configuration
- Network Setup
- Backup and Restore
- Troubleshooting
- Updating
- Limitations
Overview β
MeshMonitor can be deployed in Proxmox VE using LXC (Linux Containers) as an alternative to Docker. This deployment method provides:
- Lightweight: LXC containers have minimal overhead compared to VMs
- Integrated: Native Proxmox VE management and monitoring
- Secure: Unprivileged containers with systemd process management
- Simple: Pre-built templates for easy deployment
- Updatable: Templates are git-native from first boot β
meshmonitor-updatehandles future in-place upgrades without redeploying
Note: Docker remains the primary supported deployment method with the most features. LXC is provided as a community-supported alternative for Proxmox users.
Prerequisites β
Proxmox VE Requirements β
- Proxmox VE: Version 7.0 or later
- Storage: At least 10GB available for container
- Network: Bridge network configured (typically
vmbr0) - Resources:
- Minimum: 1 CPU core, 512MB RAM
- Recommended: 2 CPU cores, 2GB RAM, 1GB swap
Meshtastic Requirements β
- Meshtastic node accessible via TCP/IP
- Network connectivity between container and node
- Node connection is configured via the MeshMonitor web UI after first login
Quick Start β
Note: Replace <version> with the actual version number from the releases page (e.g., 4.12.0). The generic "latest" URL does not work due to GitHub's asset naming requirements.
# 1. Download template on your computer
wget https://github.com/yeraze/meshmonitor/releases/download/v<version>/meshmonitor-<version>-amd64.tar.gz
# 2. Upload to Proxmox server
scp meshmonitor-<version>-amd64.tar.gz root@YOUR-PROXMOX-IP:/var/lib/vz/template/cache/
# 3. Create container via Proxmox web UI (see Detailed Installation below)
# 4. Start container and run post-install setup
pct start CONTAINER-ID
pct enter CONTAINER-ID
bash /opt/meshmonitor/lxc/proxmox/post-install.sh
# 5. Access web UI β URL is printed by post-install.sh
# Open browser to: http://CONTAINER-IP:3001
# Default login: admin / changeme (change immediately)
# Configure your Meshtastic node via Settings -> Node ConnectionDetailed Installation β
Step 1: Download the LXC Template β
- Go to the MeshMonitor Releases page
- Find the latest release version number (e.g.,
v4.12.0) - Download the
meshmonitor-<version>-amd64.tar.gzfile for that version - Optionally download the
.sha256file to verify integrity
Example download (replace <version> with the current version):
wget https://github.com/yeraze/meshmonitor/releases/download/v<version>/meshmonitor-<version>-amd64.tar.gz
wget https://github.com/yeraze/meshmonitor/releases/download/v<version>/meshmonitor-<version>-amd64.tar.gz.sha256Verify checksum (optional):
sha256sum -c meshmonitor-<version>-amd64.tar.gz.sha256Step 2: Upload Template to Proxmox β
Upload the template to your Proxmox server's template storage:
scp meshmonitor-<version>-amd64.tar.gz root@YOUR-PROXMOX-IP:/var/lib/vz/template/cache/Step 3: Create Container from Template β
Via Proxmox Web UI: β
Navigate: Datacenter β Node β Create CT (top-right button)
General Tab:
- CT ID: Choose an available ID (e.g., 100)
- Hostname:
meshmonitor - Unprivileged container: β Checked (recommended)
- Password: Set a root password
- SSH public key: (optional)
Template Tab:
- Storage: Your template storage
- Template: Select
meshmonitor-<version>-amd64.tar.gz
Disks Tab:
- Storage: Choose your storage (e.g.,
local-lvm) - Disk size:
10 GiB(minimum),20 GiB(recommended)
- Storage: Choose your storage (e.g.,
CPU Tab:
- Cores:
2(recommended)
- Cores:
Memory Tab:
- Memory (MiB):
2048(recommended) - Swap (MiB):
1024(recommended β needed for npm build during updates)
- Memory (MiB):
Network Tab:
- Name:
eth0 - Bridge:
vmbr0(your network bridge) - IPv4: DHCP or Static IP
- IPv6: DHCP or Static IP (optional)
- Firewall: β Checked (optional)
- Name:
DNS Tab:
- Use host settings (default)
Confirm Tab:
- Review settings
- β Start after created (recommended)
- Click Finish
Via Command Line: β
# Create container (replace <version> and <storage> with actual values)
pct create 100 local:vztmpl/meshmonitor-<version>-amd64.tar.gz \
--hostname meshmonitor \
--cores 2 \
--memory 2048 \
--swap 1024 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--storage <storage> \
--rootfs <storage>:10 \
--unprivileged 1 \
--features nesting=1 \
--onboot 1
# Start container
pct start 100Step 4: Post-Install Setup β
Enter the container:
pct enter 100 # Replace 100 with your container IDRun the post-install script:
bash /opt/meshmonitor/lxc/proxmox/post-install.shThis script:
- Sets
ALLOWED_ORIGINSinmeshmonitor.envwith your container's actual IP - Populates
meshmonitor.envfrom the documented example file - Adds
/usr/local/binto PATH formeshmonitor-update - Prints the web UI URL, default login, and update instructions
Step 5: Access Web UI β
The post-install script prints your URL β open it in a browser:
http://CONTAINER-IP:3001Log in with default credentials:
- Username:
admin - Password:
changeme - Change your password immediately after first login
- Username:
Configure your Meshtastic node:
- Go to Settings β Node Connection
- Enter your node's IP address and save
Configuration β
Environment Variables β
All configuration is done via /etc/meshmonitor/meshmonitor.env. The post-install script populates this from meshmonitor.env.example with ALLOWED_ORIGINS pre-set to your container's IP. Edit it to customize further:
nano /etc/meshmonitor/meshmonitor.envKey settings:
# CORS β set to your container's IP (post-install.sh sets this automatically)
ALLOWED_ORIGINS=http://CONTAINER-IP:3001
# Optional - Server
PORT=3001
NODE_ENV=production
BASE_URL=/
# Optional - Database
DATABASE_PATH=/data/meshmonitor.db
# Optional - Security
SESSION_SECRET=your-random-secret-here
COOKIE_SECURE=false
COOKIE_SAMESITE=lax
# Optional - Notifications
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
VAPID_SUBJECT=mailto:your@email.com
# Optional - SSO/OIDC
OIDC_ISSUER=
OIDC_CLIENT_ID=
OIDC_CLIENT_SECRET=
# Optional - Logging
ACCESS_LOG_ENABLED=false
ACCESS_LOG_PATH=/data/logs/access.log
ACCESS_LOG_FORMAT=combinedSee /etc/meshmonitor/meshmonitor.env.example for the full documented list of options.
Applying Configuration Changes β
After editing /etc/meshmonitor/meshmonitor.env:
systemctl restart meshmonitor
systemctl restart meshmonitor-appriseData Directory β
All persistent data is stored in /data:
/data/
βββ meshmonitor.db # SQLite database
βββ apprise-config/ # Notification configurations
βββ scripts/ # Deployment scripts
βββ logs/ # Application logs
βββ system-backups/ # System backup filesNetwork Setup β
Port Forwarding β
MeshMonitor listens on port 3001 by default (configurable via the PORT environment variable in /etc/meshmonitor/meshmonitor.env).
To access from outside Proxmox:
- Configure Proxmox firewall rules to allow port 3001
- Or use port forwarding on your router
Note: Unlike Docker deployments which map 8080:3001, LXC containers have no port mapping layer β the app runs directly on port 3001.
Static IP Configuration β
To assign a static IP via Proxmox web UI:
- Container β Network β Edit β IPv4: Static
- Set IP/CIDR and Gateway
Or via command line on the Proxmox host:
pct set 100 --net0 name=eth0,bridge=vmbr0,ip=192.168.1.50/24,gw=192.168.1.1Backup and Restore β
Automated Backup via meshmonitor-update β
meshmonitor-update creates a backup before every update automatically. Backups are stored at /var/backups/meshmonitor/ by default and include /data/, meshmonitor.env, and systemd service files.
Manual Backup β
# Inside container
tar czf /tmp/meshmonitor-backup.tar.gz /data /etc/meshmonitor# Copy to Proxmox host
pct pull 100 /tmp/meshmonitor-backup.tar.gz ./meshmonitor-backup.tar.gzProxmox Snapshot β
# On Proxmox host
pct snapshot 100 pre-update --description "Before update"Proxmox Backup β
# On Proxmox host
vzdump 100 --storage local --compress gzip --mode snapshotTroubleshooting β
Service Status β
Check service status:
systemctl status meshmonitor
systemctl status meshmonitor-appriseView Logs β
Real-time logs:
# MeshMonitor application logs
journalctl -u meshmonitor -f
# Apprise notification logs
journalctl -u meshmonitor-apprise -f
# All MeshMonitor logs
journalctl -t meshmonitor -fHistorical logs:
# Last 100 lines
journalctl -u meshmonitor -n 100
# Since specific time
journalctl -u meshmonitor --since "1 hour ago"
# Filter by priority
journalctl -u meshmonitor -p errCommon Issues β
Service Won't Start β
Check file permissions:
ls -la /data
chown -R meshmonitor:meshmonitor /dataCheck systemd service:
systemctl cat meshmonitor
systemd-analyze verify meshmonitor.serviceNetwork Interface DOWN / No IP Address β
If ip addr show shows eth0 as state DOWN with no IP address, the container's networking service may not be running.
Check networking service:
systemctl status networkingManually bring up the interface:
ifup eth0Verify DHCP client is installed (required for ip=dhcp configuration):
which dhclientIf dhclient is missing, the container was built from an older template before the networking fix. Download the latest template from the releases page and recreate the container.
Verify Proxmox wrote the interface config:
ls /etc/network/interfaces.d/
cat /etc/network/interfacesYou should see an entry for eth0 with either dhcp or a static IP. If /etc/network/interfaces.d/ is empty, check your Proxmox container network settings in the web UI.
Cannot Connect to Meshtastic Node β
Configure your node via the web UI: Settings β Node Connection.
Test network connectivity:
# Inside container
ping YOUR-NODE-IP
# Test TCP connection to Meshtastic node
curl -s --connect-timeout 5 telnet://YOUR-NODE-IP:4403 || echo "Connection failed"Check firewall:
# On Proxmox host
pct config 100 | grep firewallWeb UI Not Accessible β
Check service is running:
systemctl status meshmonitor
ss -tln | grep 3001Check from Proxmox host:
curl http://CONTAINER-IP:3001Verify ALLOWED_ORIGINS is set correctly:
grep ALLOWED_ORIGINS /etc/meshmonitor/meshmonitor.env
# Should show: ALLOWED_ORIGINS=http://CONTAINER-IP:3001
# If missing, run: bash /opt/meshmonitor/lxc/proxmox/post-install.shVerify network configuration:
ip addr show
ip route showNative Module Crash on Startup β
If MeshMonitor fails to start after a fresh deployment with errors related to better-sqlite3, the pre-built native binary may not be compatible with your LXC container's platform. Rebuild it from source:
systemctl stop meshmonitor
apt update
apt install -y build-essential python3 make g++
cd /opt/meshmonitor
npm rebuild better-sqlite3 --build-from-source
systemctl start meshmonitorVerify it's running:
systemctl status meshmonitor --no-pager -lDatabase Locked Errors β
Check for stale processes:
ps aux | grep node
lsof /data/meshmonitor.dbRestart services:
systemctl restart meshmonitormeshmonitor-update Not Found After Self-Install β
If meshmonitor-update is not found after running the self-install:
source /root/.bashrc
# or open a new shell/usr/local/bin is not in Debian's minimal default PATH. The self-install adds it to /root/.bashrc automatically, but the current shell session needs to be reloaded.
Performance Issues β
Check resource usage:
# CPU and memory
top
# Database size
du -sh /data/meshmonitor.dbIncrease container resources (on Proxmox host):
pct set 100 --cores 4
pct set 100 --memory 4096
pct set 100 --swap 1024If meshmonitor-update runs for an excessively long time, the container likely needs more RAM or swap β npm's TypeScript build peaks at ~1.5GB Node heap.
Updating β
Templates built from v4.12.0+ are git-native from first boot. Two update paths are available:
In-place update (recommended) β
Run inside the container β no template redownload, no data migration, minimal downtime:
# First run β self-installs to /usr/local/bin:
bash /opt/meshmonitor/lxc/meshmonitor-update
# All subsequent runs:
meshmonitor-update
# Useful flags:
meshmonitor-update -s # check current vs available version
meshmonitor-update -n # dry run β preview what would change
meshmonitor-update -h # see all optionsThis performs a git pull, rebuilds the app, and restarts services in place.
Full template swap (alternative) β
Use when major OS or Node.js version changes ship, or on containers with limited resources where the npm build is impractical.
lxc/update.sh automates the destroy-and-recreate flow on the Proxmox host:
# Fetch the script:
wget https://raw.githubusercontent.com/Yeraze/meshmonitor/main/lxc/update.sh
chmod +x update.sh
# Update CT 100 to the latest release (auto-detected):
./update.sh --ctid 100
# Or pin a specific version:
./update.sh --ctid 100 --version 4.12.0
# Non-interactive (e.g. cron):
./update.sh --ctid 100 --yesThe script:
- Reads cores/memory/swap/storage/bridge/rootfs size from the existing CT.
- Takes a Proxmox snapshot (best-effort) and writes file backups of
/dataand/etc/meshmonitorto/root/meshmonitor-lxc-backups/. - Preserves the current static IP/gateway by default.
- Restarts the MeshMonitor systemd services after the rebuild.
See ./update.sh --help for all options.
Manual Update Process β
If you prefer to run each step yourself:
Create snapshot before updating:
bashpct snapshot 100 before-updateDownload new template into Proxmox's template cache:
bashwget -O /var/lib/vz/template/cache/meshmonitor-<version>-amd64.tar.gz \ https://github.com/Yeraze/meshmonitor/releases/download/v<version>/meshmonitor-<version>-amd64.tar.gzBack up data and env:
bashpct exec 100 -- tar czf /tmp/meshmonitor-data.tar.gz /data /etc/meshmonitor pct pull 100 /tmp/meshmonitor-data.tar.gz ./meshmonitor-data.tar.gzNote the current network config:
bashpct config 100 | grep net0Stop and destroy the old container:
bashpct stop 100 pct destroy 100Create the new container from the updated template (re-use the IP from step 4).
Restore data and env:
bashpct push 100 ./meshmonitor-data.tar.gz /tmp/meshmonitor-data.tar.gz pct exec 100 -- tar xzf /tmp/meshmonitor-data.tar.gz -C / pct exec 100 -- rm /tmp/meshmonitor-data.tar.gz pct exec 100 -- chown -R meshmonitor:meshmonitor /dataRun post-install and restart services:
bashpct exec 100 -- bash /opt/meshmonitor/lxc/proxmox/post-install.sh pct exec 100 -- systemctl restart meshmonitor meshmonitor-apprise pct exec 100 -- systemctl status meshmonitor --no-pager
Limitations β
Feature Limitations β
- β
In-place upgrade:
meshmonitor-updatehandles updates from v4.12.0+ templates - β Single architecture: amd64/x86_64 only (no ARM support yet)
- β Community support: LXC is best-effort, Docker is primary
Deployment Considerations β
- Templates prior to v4.12.0 had no
.gitand requiredmigrate-to-git.shbeforemeshmonitor-updatecould be used. See the migration guide. - Data and env are preserved across full template swap updates via file backup + restore
- Some Docker-specific features may not be available
Supported Features β
- β Core functionality (node monitoring, messaging, telemetry)
- β Web push notifications
- β Apprise notification integrations
- β System backups and restore
- β OIDC/SSO authentication
- β API access
- β Virtual node for mobile apps
Additional Resources β
- Main Documentation: Getting Started Guide
- Configuration Guide: Production Deployment
- Docker Deployment: Deployment Guide
- GitHub: MeshMonitor Repository
- Issues: Report Problems
Getting Help β
If you encounter issues:
- Check this troubleshooting guide
- Review the main documentation
- Search existing issues
- Ask in Discussions
- Create a new issue with:
- LXC container configuration
- Service logs (
journalctl -u meshmonitor) - Environment configuration (redact sensitive data)
- Steps to reproduce the problem