Overview
Running nanobot as a systemd user service ensures the gateway starts automatically on boot and restarts on failure. This is ideal for dedicated Linux servers or personal machines.
User services run under your user account and only start when you’re logged in. To keep nanobot running after logout, you’ll need to enable lingering (see below).
Prerequisites
Linux system with systemd (Ubuntu 16.04+, Debian 8+, RHEL 7+, etc.)
nanobot installed via pip, uv, or from source
Completed initial configuration (nanobot onboard)
Quick Setup
Find nanobot binary path
Locate where nanobot is installed: Common locations:
pip/uv : ~/.local/bin/nanobot
uv tool : ~/.local/bin/nanobot
pip (system) : /usr/local/bin/nanobot
From source : <venv>/bin/nanobot
Create service file
Create the systemd user service directory: mkdir -p ~/.config/systemd/user
Create the service file at ~/.config/systemd/user/nanobot-gateway.service: [Unit]
Description =Nanobot Gateway
After =network.target
[Service]
Type =simple
ExecStart =%h/.local/bin/nanobot gateway
Restart =always
RestartSec =10
NoNewPrivileges =yes
ProtectSystem =strict
ReadWritePaths =%h
[Install]
WantedBy =default.target
%h expands to your home directory. If your nanobot is installed elsewhere, update the ExecStart path.
Enable and start the service
Reload systemd to recognize the new service: systemctl --user daemon-reload
Enable and start the service: systemctl --user enable --now nanobot-gateway
enable: Starts automatically on login
--now: Starts the service immediately
Verify it's running
Check the service status: systemctl --user status nanobot-gateway
You should see: ● nanobot-gateway.service - Nanobot Gateway
Loaded: loaded (/home/user/.config/systemd/user/nanobot-gateway.service; enabled)
Active: active (running) since ...
Enable Lingering (Run After Logout)
By default, user services stop when you log out. To keep nanobot running 24/7:
loginctl enable-linger $USER
This allows your user services to run even when you’re not logged in.
Verify lingering is enabled: loginctl show-user $USER | grep Linger
Should output: Linger=yes
Service Management
Common Commands
# Check status
systemctl --user status nanobot-gateway
# Start service
systemctl --user start nanobot-gateway
# Stop service
systemctl --user stop nanobot-gateway
# Restart (after config changes)
systemctl --user restart nanobot-gateway
# Disable auto-start
systemctl --user disable nanobot-gateway
# Re-enable auto-start
systemctl --user enable nanobot-gateway
# View logs (last 50 lines)
journalctl --user -u nanobot-gateway -n 50
# Follow logs in real-time
journalctl --user -u nanobot-gateway -f
# View logs since last boot
journalctl --user -u nanobot-gateway -b
After Config Changes
When you edit ~/.nanobot/config.json, restart the service:
systemctl --user restart nanobot-gateway
After Service File Changes
If you modify the .service file itself, reload systemd first:
systemctl --user daemon-reload
systemctl --user restart nanobot-gateway
Advanced Configuration
Custom Workspace or Config Path
If you want to use a non-default workspace or config file:
[Service]
ExecStart =%h/.local/bin/nanobot gateway -w /opt/nanobot/workspace -c /opt/nanobot/config.json
Environment Variables
Set environment variables for API keys or other settings:
[Service]
Environment = "OPENROUTER_API_KEY=sk-or-v1-xxx"
Environment = "BRAVE_API_KEY=BSA-xxx"
ExecStart =%h/.local/bin/nanobot gateway
For sensitive data, use EnvironmentFile instead: [Service]
EnvironmentFile =%h/.nanobot/.env
ExecStart =%h/.local/bin/nanobot gateway
Create ~/.nanobot/.env: OPENROUTER_API_KEY = sk-or-v1-xxx
BRAVE_API_KEY = BSA-xxx
Resource Limits
Limit CPU and memory usage:
[Service]
CPUQuota =100% # Max 1 CPU core
MemoryMax =1G # Max 1GB RAM
MemoryHigh =800M # Throttle at 800MB
ExecStart =%h/.local/bin/nanobot gateway
Custom Port
Run on a different port:
[Service]
ExecStart =%h/.local/bin/nanobot gateway -p 8080
Hardened Security
For production deployments, add additional security restrictions:
[Service]
Type =simple
ExecStart =%h/.local/bin/nanobot gateway
# Restart policy
Restart =always
RestartSec =10
# Security hardening
NoNewPrivileges =yes
PrivateTmp =yes
ProtectSystem =strict
ProtectHome =read-only
ReadWritePaths =%h/.nanobot
ProtectKernelTunables =yes
ProtectKernelModules =yes
ProtectControlGroups =yes
RestrictAddressFamilies =AF_INET AF_INET6 AF_UNIX
RestrictNamespaces =yes
RestrictRealtime =yes
RestrictSUIDSGID =yes
LockPersonality =yes
SystemCallFilter =@system-service
SystemCallErrorNumber =EPERM
These restrictions may prevent certain tools from working. Test thoroughly before deploying to production.
Multiple Instances
Run multiple nanobot instances with different configurations:
Create Service Files
Telegram bot (~/.config/systemd/user/nanobot-telegram.service):
[Unit]
Description =Nanobot Gateway (Telegram)
After =network.target
[Service]
Type =simple
ExecStart =%h/.local/bin/nanobot gateway -w %h/.nanobot/telegram -c %h/.nanobot/telegram/config.json -p 18791
Restart =always
RestartSec =10
[Install]
WantedBy =default.target
Discord bot (~/.config/systemd/user/nanobot-discord.service):
[Unit]
Description =Nanobot Gateway (Discord)
After =network.target
[Service]
Type =simple
ExecStart =%h/.local/bin/nanobot gateway -w %h/.nanobot/discord -c %h/.nanobot/discord/config.json -p 18792
Restart =always
RestartSec =10
[Install]
WantedBy =default.target
Enable Both Services
systemctl --user daemon-reload
systemctl --user enable --now nanobot-telegram nanobot-discord
See Multiple Instances for more details.
System-Wide Service (Root)
For system-wide deployment (runs as root or dedicated user):
Create system service file
Create /etc/systemd/system/nanobot-gateway.service: [Unit]
Description =Nanobot Gateway (System)
After =network.target
[Service]
Type =simple
User =nanobot
Group =nanobot
WorkingDirectory =/opt/nanobot
ExecStart =/usr/local/bin/nanobot gateway -w /opt/nanobot/workspace -c /opt/nanobot/config.json
Restart =always
RestartSec =10
[Install]
WantedBy =multi-user.target
Create dedicated user
sudo useradd -r -s /bin/ false nanobot
sudo mkdir -p /opt/nanobot/workspace
sudo chown -R nanobot:nanobot /opt/nanobot
Enable and start
sudo systemctl daemon-reload
sudo systemctl enable --now nanobot-gateway
Running as root is not recommended. Always use a dedicated user with minimal permissions.
Monitoring and Alerts
Email Alerts on Failure
Send an email when the service fails:
[Unit]
Description =Nanobot Gateway
After =network.target
OnFailure =failure-email@%i.service
Create /etc/systemd/system/[email protected] (requires sendmail):
[Unit]
Description =Send email on %i failure
[Service]
Type =oneshot
ExecStart =/bin/sh -c 'echo "Service %i failed" | sendmail -t root@localhost'
Watchdog
Enable systemd watchdog to detect hung processes:
[Service]
WatchdogSec =30s
ExecStart =%h/.local/bin/nanobot gateway
nanobot must send watchdog pings to systemd. This is not currently implemented but can be added if needed.
Troubleshooting
Service Won’t Start
Check status and logs:
systemctl --user status nanobot-gateway
journalctl --user -u nanobot-gateway -n 50
Common issues:
ExecStart path is incorrect
Verify the path to nanobot: Update ExecStart in the service file to match.
Ensure ~/.nanobot/config.json exists: ls -la ~/.nanobot/config.json
Run nanobot onboard if missing.
Check if port 18790 is in use: Either stop the conflicting service or use a different port with -p.
Check file permissions: chmod +x $( which nanobot )
chmod 644 ~/.config/systemd/user/nanobot-gateway.service
View recent logs:
journalctl --user -u nanobot-gateway -n 100
Common causes:
Missing API keys in config.json
Invalid JSON syntax in config
Python dependencies not installed
Network issues preventing channel connections
Service Doesn’t Start on Boot
Ensure service is enabled:
systemctl --user is-enabled nanobot-gateway
Should output: enabled
If disabled, enable it:
systemctl --user enable nanobot-gateway
Enable lingering:
loginctl enable-linger $USER
Can’t See Logs
Increase journal retention:
Edit /etc/systemd/journald.conf:
[Journal]
SystemMaxUse =500M
MaxRetentionSec =1month
Restart journald:
sudo systemctl restart systemd-journald
High Memory Usage
Check current usage:
systemctl --user status nanobot-gateway
Add memory limits:
[Service]
MemoryMax =1G
MemoryHigh =800M
Reload and restart:
systemctl --user daemon-reload
systemctl --user restart nanobot-gateway
Startup Optimization
Add a startup delay if network isn’t ready:
[Unit]
After =network-online.target
Wants =network-online.target
[Service]
ExecStartPre =/bin/sleep 5
ExecStart =%h/.local/bin/nanobot gateway
Log Management
Reduce log verbosity:
# In config.json, add:
{
"logging" : {
"level" : "INFO" # or WARNING, ERROR
}
}
Rotate logs automatically (systemd does this by default):
# View journal disk usage
journalctl --disk-usage
# Clean old logs
journalctl --vacuum-time=7d
Best Practices
Integration with Other Services
Start After Database Service
If nanobot depends on a local database:
[Unit]
After =postgresql.service
Wants =postgresql.service
Coordinate with Backup Service
Prevent backups during gateway restarts:
[Unit]
Conflicts =nanobot-gateway.service
Next Steps
Docker Deployment Alternative containerized deployment method
Multiple Instances Run multiple isolated nanobot instances
Monitoring Set up monitoring and observability
Configuration Complete configuration reference