Overview
m87-server handles device registration, authentication, and tunnel relay. It connects m87 runtimes on edge devices to m87 CLI users. Self-hosting allows you to:- Keep all device data within your infrastructure
- Customize authentication and access control
- Meet compliance requirements
- Control updates and maintenance windows
Requirements
- MongoDB: Version 8 or later (for device and user data storage)
- Docker (recommended): For containerized deployment
- TLS Certificate: For production deployments (Let’s Encrypt or custom)
- Public IP/Domain: For device and client connectivity
Quick Start with Docker Compose
Configure Environment
Create a Edit the
.env file with your configuration:.env file with your settings (see Configuration below).Start the Server
- m87-server (API and tunnel relay)
- MongoDB (database)
- Watchtower (optional auto-updates)
Configuration
The m87 server is configured via environment variables. Below are the key settings:Core Database
MongoDB connection string used by m87-serverDefault:
mongodb://mongo:27017Logical database name used by m87-server
MongoDB root username (required for secured MongoDB setups)
MongoDB root password (required for secured MongoDB setups)
Authentication & OAuth
OAuth/OIDC issuer URL used to validate access tokensDefault: For custom auth, use your Auth0 tenant or OIDC provider.
https://auth.make87.com/Expected OAuth audience for access tokens (must match the
aud claim)Default: https://auth.make87.comServer Networking
Public base address where this server is reachableDefault: Used to check SNI of incoming requests for device ID prefixes.
localhostPort for the unified public interface (runtime connections and tunnel traffic)This should be mapped to port 443 for TLS.
Port for the REST APIUsed for WebTransport endpoint for the web app (typically mapped to 8080).
Admin & Security
Static admin API key for privileged actionsUsed for approving users, creating organizations, and bootstrapping admin access.
Comma-separated list of email addresses that receive admin privileges
User Management
Whether newly registered users require manual approval
true: User accounts start inactive until approvedfalse: Users are active immediately
Domains that are auto-approved on signupComma-separated list (no spaces). If a user’s email domain matches, approval is skipped.
Device Sharing
Whether devices can be shared across different organizations
true: Cross-org device sharing allowedfalse: Devices are restricted to their organization
Data Retention
Number of days audit log entries are retainedOlder entries are automatically deleted.
Number of days deployment/report data is retainedOlder reports are automatically deleted.
Other Settings
Whether the server runs in staging mode
0: Production behavior1: Staging mode with relaxed checks and verbose logging
Logging levelOptions:
error, warn, info, debug, tracePath for TLS certificates
Exposed Ports
The docker-compose configuration exposes:- 443 → 8084 (TCP/UDP): Runtime connections and tunnel traffic (TLS)
- 8080 → 8085 (UDP): REST API and WebTransport endpoint
Example Configuration
Here’s a complete example.env file for production:
Building from Source
If you prefer to build the server binary yourself:Using Prebuilt Docker Images
Pull the latest image from GitHub Container Registry:Auto-Updates with Watchtower
The docker-compose file includes Watchtower for automatic updates:- Check for new images every 5 minutes
- Automatically pull and restart with latest version
- Only update containers with the
watchtower.enablelabel
Production Deployment Checklist
Secure MongoDB
- Set strong
MONGO_INITDB_ROOT_PASSWORD - Restrict MongoDB port access (only to m87-server)
- Enable MongoDB authentication
Configure TLS
- Obtain TLS certificate (Let’s Encrypt recommended)
- Configure reverse proxy (nginx, Caddy) or mount certificates
- Ensure port 443 routes to
UNIFIED_PORT
Set Admin Credentials
- Change
ADMIN_KEYfrom default - Configure
ADMIN_EMAILS - Set
USERS_NEED_APPROVALbased on your requirements
Configure Authentication
If using custom OAuth:
- Set up OAuth provider (Auth0, Keycloak, etc.)
- Update
OAUTH_ISSUERandOAUTH_AUDIENCE - Ensure tokens include required claims
Set Public Address
- Update
PUBLIC_ADDRESSto your domain - Ensure DNS points to your server
- Verify firewall allows ports 443 and 8080
Configure Monitoring
- Set appropriate
RUST_LOGlevel - Set up log aggregation
- Monitor container health
Client Configuration
After deploying your server, configure clients to use it:Troubleshooting
Server not starting
Server not starting
Check logs:Common issues:
- MongoDB connection failed (check
MONGO_URI) - Invalid OAuth configuration
- Port already in use
Devices can't connect
Devices can't connect
Verify:
PUBLIC_ADDRESSis correct and DNS resolves- Port 443 is accessible from internet
- TLS certificate is valid
- Firewall allows incoming connections
Authentication errors
Authentication errors
Check:
OAUTH_ISSUERandOAUTH_AUDIENCEmatch your provider- OAuth provider is reachable
- Tokens include required claims
- Admin key is correct
Database connection issues
Database connection issues
- Verify MongoDB is running:
docker compose ps mongo - Check MongoDB logs:
docker compose logs mongo - Ensure credentials in
.envmatch MongoDB config
Updating
Manual Update
With Watchtower (Automatic)
If running with theauto-update profile, Watchtower handles updates automatically.