Skip to main content

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

1

Find nanobot binary path

Locate where nanobot is installed:
which nanobot
Common locations:
  • pip/uv: ~/.local/bin/nanobot
  • uv tool: ~/.local/bin/nanobot
  • pip (system): /usr/local/bin/nanobot
  • From source: <venv>/bin/nanobot
2

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:
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.
3

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
4

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:
nanobot-gateway.service
[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:
nanobot-gateway.service
[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:
nanobot-gateway.service
[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:
nanobot-gateway.service
[Service]
ExecStart=%h/.local/bin/nanobot gateway -p 8080

Hardened Security

For production deployments, add additional security restrictions:
nanobot-gateway.service
[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):
1

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
2

Create dedicated user

sudo useradd -r -s /bin/false nanobot
sudo mkdir -p /opt/nanobot/workspace
sudo chown -R nanobot:nanobot /opt/nanobot
3

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:
nanobot-gateway.service
[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:
nanobot-gateway.service
[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:
Verify the path to nanobot:
which 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:
ss -tlnp | grep 18790
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

Service Starts Then Immediately Stops

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:
nanobot-gateway.service
[Service]
MemoryMax=1G
MemoryHigh=800M
Reload and restart:
systemctl --user daemon-reload
systemctl --user restart nanobot-gateway

Performance Tuning

Startup Optimization

Add a startup delay if network isn’t ready:
nanobot-gateway.service
[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:
nanobot-gateway.service
[Unit]
After=postgresql.service
Wants=postgresql.service

Coordinate with Backup Service

Prevent backups during gateway restarts:
nanobot-backup.service
[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

Build docs developers (and LLMs) love