-
Notifications
You must be signed in to change notification settings - Fork 0
Deployment
This guide covers deploying BenchMesh for production use, including systemd services, Docker containers, reverse proxies, and security considerations.
- Deployment Options
- Systemd Service
- Docker Deployment
- Reverse Proxy Setup
- Security Hardening
- Monitoring
- Backup and Recovery
- Performance Tuning
BenchMesh can be deployed in several ways:
- Local Service - Run directly on the hardware with instruments
- Systemd Service - Auto-start on boot with systemd
- Docker Container - Containerized deployment
- Remote Access - Expose via reverse proxy with SSL
Create a systemd unit file for automatic startup:
sudo nano /etc/systemd/system/benchmesh.service[Unit]
Description=BenchMesh Serial Service
After=network.target
[Service]
Type=simple
User=benchmesh
Group=dialout
WorkingDirectory=/opt/benchmesh
Environment="PYTHONPATH=/opt/benchmesh/benchmesh-serial-service/src"
Environment="BENCHMESH_CONFIG=/opt/benchmesh/config.yaml"
ExecStart=/opt/benchmesh/venv/bin/uvicorn benchmesh_service.api:app --host 0.0.0.0 --port 57666
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/benchmesh/logs
[Install]
WantedBy=multi-user.target# Create dedicated user
sudo useradd -r -s /bin/false -G dialout benchmesh
# Create installation directory
sudo mkdir -p /opt/benchmesh
sudo chown benchmesh:dialout /opt/benchmesh
# Clone repository
cd /opt/benchmesh
sudo -u benchmesh git clone https://github.com/MarkoVcode/BenchMesh.git .
# Create virtual environment
sudo -u benchmesh python3 -m venv venv
sudo -u benchmesh venv/bin/pip install -r benchmesh-serial-service/requirements.txt
# Create logs directory
sudo -u benchmesh mkdir -p /opt/benchmesh/logs
# Copy config file
sudo -u benchmesh cp config.yaml.example config.yaml
sudo -u benchmesh nano config.yaml # Edit configuration
# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable benchmesh
sudo systemctl start benchmesh
# Check status
sudo systemctl status benchmesh# Start service
sudo systemctl start benchmesh
# Stop service
sudo systemctl stop benchmesh
# Restart service
sudo systemctl restart benchmesh
# View logs
sudo journalctl -u benchmesh -f
# View recent errors
sudo journalctl -u benchmesh -p err
# Enable auto-start on boot
sudo systemctl enable benchmesh
# Disable auto-start
sudo systemctl disable benchmeshCreate a separate service for Node-RED:
sudo nano /etc/systemd/system/benchmesh-nodered.service[Unit]
Description=BenchMesh Node-RED
After=network.target benchmesh.service
[Service]
Type=simple
User=benchmesh
Group=dialout
WorkingDirectory=/opt/benchmesh
Environment="NODE_RED_HOME=/opt/benchmesh/.node-red"
ExecStart=/usr/bin/node-red
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reload
sudo systemctl enable benchmesh-nodered
sudo systemctl start benchmesh-noderedCreate Dockerfile in repository root:
FROM python:3.10-slim
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
&& rm -rf /var/lib/apt/lists/*
# Create app directory
WORKDIR /app
# Copy requirements
COPY benchmesh-serial-service/requirements.txt .
# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY benchmesh-serial-service/ benchmesh-serial-service/
COPY config.yaml .
# Create logs directory
RUN mkdir -p logs
# Expose port
EXPOSE 57666
# Set environment
ENV PYTHONPATH=/app/benchmesh-serial-service/src
ENV BENCHMESH_CONFIG=/app/config.yaml
# Run application
CMD ["uvicorn", "benchmesh_service.api:app", "--host", "0.0.0.0", "--port", "57666"]Create docker-compose.yml:
version: '3.8'
services:
benchmesh:
build: .
container_name: benchmesh
ports:
- "57666:57666"
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0" # Map serial devices
- "/dev/ttyUSB1:/dev/ttyUSB1"
volumes:
- ./config.yaml:/app/config.yaml:ro
- ./logs:/app/logs
restart: unless-stopped
environment:
- PYTHONPATH=/app/benchmesh-serial-service/src
- BENCHMESH_CONFIG=/app/config.yaml
nodered:
image: nodered/node-red:latest
container_name: benchmesh-nodered
ports:
- "1880:1880"
volumes:
- node-red-data:/data
depends_on:
- benchmesh
restart: unless-stopped
volumes:
node-red-data:# Build image
docker-compose build
# Start services
docker-compose up -d
# View logs
docker-compose logs -f benchmesh
# Stop services
docker-compose down
# Restart service
docker-compose restart benchmesh
# Update and restart
git pull
docker-compose build
docker-compose up -dSerial devices require privileged access:
services:
benchmesh:
privileged: true # Required for serial devices
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
- "/dev/ttyUSB1:/dev/ttyUSB1"Or use device group permissions:
services:
benchmesh:
group_add:
- dialout
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"Create /etc/nginx/sites-available/benchmesh:
# HTTP -> HTTPS redirect
server {
listen 80;
server_name benchmesh.example.com;
return 301 https://$server_name$request_uri;
}
# HTTPS server
server {
listen 443 ssl http2;
server_name benchmesh.example.com;
# SSL certificates (use certbot for Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/benchmesh.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/benchmesh.example.com/privkey.pem;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# Proxy to BenchMesh
location / {
proxy_pass http://localhost:57666;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
# Optional: Basic authentication
# auth_basic "BenchMesh Lab Access";
# auth_basic_user_file /etc/nginx/.htpasswd;
}
# Node-RED (optional)
server {
listen 443 ssl http2;
server_name nodered.example.com;
ssl_certificate /etc/letsencrypt/live/nodered.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nodered.example.com/privkey.pem;
location / {
proxy_pass http://localhost:1880;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Enable the site:
# Create symbolic link
sudo ln -s /etc/nginx/sites-available/benchmesh /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload nginx
sudo systemctl reload nginx# Install certbot
sudo apt-get install certbot python3-certbot-nginx
# Obtain certificate
sudo certbot --nginx -d benchmesh.example.com
# Auto-renewal (certbot sets up cron job automatically)
sudo certbot renew --dry-runCreate /etc/apache2/sites-available/benchmesh.conf:
<VirtualHost *:80>
ServerName benchmesh.example.com
Redirect permanent / https://benchmesh.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName benchmesh.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/benchmesh.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/benchmesh.example.com/privkey.pem
ProxyPreserveHost On
ProxyPass / http://localhost:57666/
ProxyPassReverse / http://localhost:57666/
# WebSocket support
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:57666/$1 [P,L]
</VirtualHost>Enable required modules and site:
sudo a2enmod proxy proxy_http proxy_wstunnel ssl rewrite
sudo a2ensite benchmesh
sudo systemctl reload apache2- Firewall Configuration:
# Allow SSH
sudo ufw allow 22/tcp
# Allow HTTP/HTTPS (if using reverse proxy)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Block direct access to BenchMesh (use reverse proxy only)
sudo ufw deny 57666/tcp
# Enable firewall
sudo ufw enable- SSH Tunnel for remote access (no reverse proxy):
# From remote machine
ssh -L 57666:localhost:57666 user@lab-server
# Access via http://localhost:57666-
Create dedicated user (see Systemd Service section)
-
File permissions:
# Set ownership
sudo chown -R benchmesh:dialout /opt/benchmesh
# Restrict config file
sudo chmod 600 /opt/benchmesh/config.yaml
# Restrict logs directory
sudo chmod 750 /opt/benchmesh/logs- Environment isolation:
# Use virtual environment
python3 -m venv venv
source venv/bin/activate- Update dependencies regularly:
pip list --outdated
pip install --upgrade -r requirements.txtBenchMesh has no built-in authentication. Add authentication via:
- Nginx Basic Auth:
# Create password file
sudo apt-get install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd admin
# Add to nginx config
auth_basic "BenchMesh";
auth_basic_user_file /etc/nginx/.htpasswd;- OAuth2 Proxy:
# Install oauth2-proxy
wget https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.4.0/oauth2-proxy-v7.4.0.linux-amd64.tar.gz
tar xzf oauth2-proxy-v7.4.0.linux-amd64.tar.gz
# Configure oauth2-proxy for Google/GitHub/etc.
./oauth2-proxy --upstream=http://localhost:57666 --http-address=0.0.0.0:4180- Centralized logging with Loki (optional):
# docker-compose.yml
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
volumes:
- loki-data:/loki
promtail:
image: grafana/promtail:latest
volumes:
- ./logs:/var/log/benchmesh:ro
- ./promtail-config.yaml:/etc/promtail/config.yaml
command: -config.file=/etc/promtail/config.yaml
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana- System monitoring with htop/glances:
sudo apt-get install htop glances
htopCreate health check endpoint in api.py:
@app.get("/health")
async def health_check():
"""Health check endpoint for monitoring."""
return {
"status": "healthy",
"timestamp": datetime.now().isoformat(),
"devices": len(manager.connections)
}Monitor with:
# Simple HTTP check
curl http://localhost:57666/health
# Continuous monitoring
watch -n 10 curl -s http://localhost:57666/healthUse external service like:
Or self-hosted:
# Create backup script
cat > /opt/benchmesh/backup.sh <<'EOF'
#!/bin/bash
BACKUP_DIR="/opt/benchmesh/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
# Backup config
cp /opt/benchmesh/config.yaml "$BACKUP_DIR/config_$TIMESTAMP.yaml"
# Backup Node-RED flows
cp -r /opt/benchmesh/.node-red "$BACKUP_DIR/node-red_$TIMESTAMP"
# Remove old backups (keep last 30 days)
find "$BACKUP_DIR" -type f -mtime +30 -delete
echo "Backup completed: $TIMESTAMP"
EOF
chmod +x /opt/benchmesh/backup.sh
# Schedule daily backup
sudo crontab -e
# Add: 0 2 * * * /opt/benchmesh/backup.sh# Restore config
cp /opt/benchmesh/backups/config_YYYYMMDD_HHMMSS.yaml /opt/benchmesh/config.yaml
# Restore Node-RED flows
rm -rf /opt/benchmesh/.node-red
cp -r /opt/benchmesh/backups/node-red_YYYYMMDD_HHMMSS /opt/benchmesh/.node-red
# Restart services
sudo systemctl restart benchmesh
sudo systemctl restart benchmesh-noderedAdjust polling intervals in driver manifests:
{
"polling": {
"methods": ["poll_status"],
"interval": 5.0 // Increase interval to reduce CPU load
}
}- Use PyPy for improved performance (optional):
sudo apt-get install pypy3
pypy3 -m venv venv
venv/bin/pip install -r requirements.txt- Increase worker processes (if using gunicorn):
gunicorn benchmesh_service.api:app \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:57666- Increase open file limits:
# Edit /etc/security/limits.conf
benchmesh soft nofile 4096
benchmesh hard nofile 8192- Disable USB autosuspend:
# Edit /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash usbcore.autosuspend=-1"
# Update grub
sudo update-grubBefore deploying to production:
- Create dedicated user account
- Set up systemd service with auto-restart
- Configure firewall (ufw/iptables)
- Set up SSL with Let's Encrypt
- Configure reverse proxy (nginx/apache)
- Enable authentication (basic auth or OAuth)
- Set up log rotation
- Configure automated backups
- Set up monitoring and health checks
- Test recovery procedures
- Document deployment steps
- Create runbook for common issues
- Getting Started - Initial setup
- Configuration - Config file format
- Troubleshooting - Common issues
- Security Hardening - Advanced security