Systemd Integration Guide for Robustel Gateway

Systemd Integration Guide for Robustel Gateway

Overview

This guide demonstrates how to integrate existing Linux applications into Robustel gateways using standard systemd service management. Applications managed by systemd run independently from the router service and follow standard Linux daemon conventions.

When to Use Systemd Integration

Choose systemd management if your application:

  • Does not require Web UI configuration developed by Robustel SDK

  • Is a standard Linux service (database, message broker, monitoring agent, etc.)

  • Requires simple deployment with minimal integration

Quick Start

Prerequisites

  • Your application binary (e.g., /path/to/myapp)

  • Application should handle SIGTERM signals for graceful shutdown

  • Basic knowledge of systemd and Debian packaging

5-Step Integration Process

  1. Create systemd service file

  2. Create Debian package structure

  3. Create Debian control files

  4. Build Debian package

  5. Install and test

Integration Method

Step 1: Create Systemd Service File

Create /lib/systemd/system/myapp.service:

[Unit]
Description=My Application Service
Documentation=man:myapp(8)
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=5

# Main process
ExecStart=/usr/bin/myapp

# Graceful shutdown
ExecStop=/bin/kill -SIGTERM $MAINPID
TimeoutStopSec=10

# Optional: Run as specific user
# User=myapp
# Group=myapp

# Optional: Resource limits
# LimitNOFILE=65536
# MemoryLimit=512M

[Install]
WantedBy=multi-user.target

Service Type Options:

TypeUse Case
simpleApplication runs in foreground (most common)
forkingApplication daemonizes itself
oneshotShort-lived initialization tasks
notifyApplication supports systemd notification

Step 2: Create Debian Package Structure

# Create packaging directory
mkdir -p myapp_1.0.0
cd myapp_1.0.0

# Create directory structure
mkdir -p debian
mkdir -p usr/bin
mkdir -p lib/systemd/system

# Copy your binary
cp /path/to/your/myapp usr/bin/
chmod +x usr/bin/myapp

# Copy systemd service file
cp /path/to/myapp.service lib/systemd/system/

Directory Structure:

myapp_1.0.0/
├── usr/
│ └── bin/
│ └── myapp # Your application binary
├── lib/
│ └── systemd/
│ └── system/
│ └── myapp.service # Systemd service file
└── debian/
├── control # Package metadata
├── changelog # Version history
├── rules # Build rules
├── compat # Debian compatibility
├── postinst # Post-installation script
└── prerm # Pre-removal script

Step 3: Create Debian Control Files

debian/control

Source: myapp
Section: net
Priority: optional
Maintainer: Your Name <your.email@company.com>
Build-Depends: debhelper (>= 11)
Standards-Version: 4.1.4

Package: myapp
Architecture: armhf
Depends: ${shlibs:Depends}, ${misc:Depends}, systemd
Description: My Application Service
Brief description of your application.
Additional details about what it does.

Note: Change Architecture:

  • armhf for EG5100, LG5100, R1520LG, EV8100, EG5101

  • arm64 for EG5200, EG5120, EG3110

debian/changelog

myapp (1.0.0) unstable; urgency=low

* Initial release with systemd support

-- Your Name <your.email@company.com> Mon, 30 Sep 2025 10:00:00 +0800

debian/rules

#!/usr/bin/make -f

%:
dh $@ --with systemd

override_dh_auto_install:
install -D -m 0755 usr/bin/myapp $(CURDIR)/debian/myapp/usr/bin/myapp
install -D -m 0644 lib/systemd/system/myapp.service $(CURDIR)/debian/myapp/lib/systemd/system/myapp.service

debian/compat

11

debian/postinst

#!/bin/sh
set -e

case "$1" in
configure)
# Reload systemd daemon
systemctl daemon-reload

# Enable service (auto-start on boot)
systemctl enable myapp.service

# Start service
systemctl start myapp.service

echo "myapp service installed and started"
;;
esac

exit 0

debian/prerm

#!/bin/sh
set -e

case "$1" in
remove)
# Stop and disable service before uninstall
systemctl stop myapp.service || true
systemctl disable myapp.service || true
;;
esac

exit 0

Make scripts executable:

chmod +x debian/postinst debian/prerm

Step 4: Build Debian Package

# Go back to parent directory
cd ..

# Build package
cd myapp_1.0.0
debuild -us -uc -b
cd ..

# Result: myapp_1.0.0_armhf.deb (or arm64)
ls -lh myapp_*.deb

Step 5: Install and Test

# Install package
sudo dpkg -i myapp_1.0.0_armhf.deb

# Verify systemd recognizes the service
systemctl status myapp

# Check if enabled (auto-start on boot)
systemctl is-enabled myapp

# Check if running
systemctl is-active myapp

# View logs
journalctl -u myapp -f

Common Management Commands

# Start service
sudo systemctl start myapp

# Stop service
sudo systemctl stop myapp

# Restart service
sudo systemctl restart myapp

# Check status (detailed)
systemctl status myapp

# View real-time logs
journalctl -u myapp -f

# View last 50 lines of logs
journalctl -u myapp -n 50

# Enable auto-start on boot
sudo systemctl enable myapp

# Disable auto-start
sudo systemctl disable myapp

# Reload service file (after editing)
sudo systemctl daemon-reload
sudo systemctl restart myapp

# Check service configuration
systemctl cat myapp

# Show service properties
systemctl show myapp

Integration Example

Example 1: Node.js Monitoring Agent

Scenario: Running a Node.js application that monitors system health.

Requirements:

  • Run as non-root user

  • Environment variables

  • Auto-restart on crash

Service File (/lib/systemd/system/monitor-agent.service):

[Unit]
Description=System Monitoring Agent
After=network.target

[Service]
Type=simple
User=monitor
Group=monitor
WorkingDirectory=/opt/monitor-agent
Environment="NODE_ENV=production"
Environment="LOG_LEVEL=info"
ExecStart=/usr/bin/node /opt/monitor-agent/index.js
Restart=always
RestartSec=10

# Restart limits (max 5 restarts within 5 minutes)
StartLimitBurst=5
StartLimitIntervalSec=300

# Resource limits
MemoryLimit=256M
LimitNOFILE=4096

[Install]
WantedBy=multi-user.target

Package Structure:

monitor-agent_1.0.0/
├── usr/
│ └── bin/
│ └── node -> /usr/local/bin/node # Symlink to Node.js
├── opt/
│ └── monitor-agent/
│ ├── index.js
│ ├── package.json
│ └── node_modules/
└── lib/
└── systemd/
└── system/
└── monitor-agent.service

Migration Checklist

Before Integration

  • Test application manually
  # Run your application manually to verify it works
/path/to/myapp
  • Check dependencies
  # Check required libraries
ldd /path/to/myapp
  • Verify signal handling

    • Application handles SIGTERM gracefully

    • No orphaned processes after shutdown

  • Document requirements

    • Required configuration files

    • Environment variables

    • User/group requirements

    • Resource requirements (memory, CPU, disk)

During Integration

  • Create service file

    • Choose correct Type= setting

    • Set appropriate restart policy

    • Configure resource limits

    • Add security hardening if needed

  • Create Debian package

    • All control files created

    • Correct architecture specified

    • Dependencies listed

    • Postinst and prerm scripts ready

  • Build package

debuild -us -uc -b

After Installation

  • Service starts successfully
systemctl status myapp
# Should show "active (running)"
  • Service enabled for auto-start
  systemctl is-enabled myapp
# Should return "enabled"
  • Logs are clean with no errors
  journalctl -u myapp -n 50
# Check for errors
  • Restart on failure works
  # Kill the process
sudo kill -9 $(pidof myapp)
sleep 10
# Service should auto-restart
systemctl status myapp
  • Boot persistence test
  sudo reboot
# After reboot:
systemctl status myapp
# Should be running

Troubleshooting

Issue 1: Service Fails to Start

Symptoms:

systemctl start myapp
# Job for myapp.service failed

Diagnosis:

# Check detailed status
systemctl status myapp -l

# View recent logs
journalctl -u myapp -n 50

# Check service file syntax
systemd-analyze verify /lib/systemd/system/myapp.service

Common Causes and Solutions:

CauseSolution
Binary not foundVerify path in ExecStart=
Permission deniedCheck binary is executable: chmod +x /usr/bin/myapp
Missing librariesInstall dependencies: apt install
Wrong Type= settingChange from forking to simple (or vice versa)

Fix and Retry:

# After fixing service file
sudo systemctl daemon-reload
sudo systemctl start myapp

Issue 2: Service Doesn't Restart After Failure

Symptoms:

  • Application crashes but doesn't restart

  • Service shows "failed" status

Solution: Add or update restart policy in service file:

[Service]
Restart=always
RestartSec=5
StartLimitBurst=5
StartLimitIntervalSec=300

Then reload:

sudo systemctl daemon-reload
sudo systemctl restart myapp

Issue 3: Service Not Enabled at Boot

Symptoms:

  • Service runs manually but doesn't start after reboot

Solution:

# Enable service
sudo systemctl enable myapp

# Verify
systemctl is-enabled myapp
# Should return "enabled"

# Test with reboot
sudo reboot
# After reboot, check:
systemctl status myapp

Issue 4: Permission Errors

Symptoms:

Permission denied
Failed to open configuration file

Solution:

  1. Run as specific user:
[Service]
User=myappuser
Group=myappuser
  1. Create user and set permissions:
sudo useradd -r -s /bin/false myappuser
sudo chown -R myappuser:myappuser /opt/myapp
sudo chmod 755 /usr/bin/myapp

Issue 5: High Resource Usage

Symptoms:

  • Service consuming too much memory/CPU

  • Gateway becomes slow

Solution: Add resource limits in service file:

[Service]
MemoryLimit=256M
MemoryHigh=200M
CPUQuota=50%
LimitNOFILE=1024
TasksMax=50

Monitor usage:

# Check resource usage
systemctl status myapp

# Detailed resource information
systemd-cgtop

Debug Commands

# View full service output
journalctl -u myapp --no-pager

# Follow logs in real-time
journalctl -u myapp -f

# Check logs since specific time
journalctl -u myapp --since "10 minutes ago"

# Check service dependencies
systemctl list-dependencies myapp

# Show all service properties
systemctl show myapp

# Check if process is running
pidof myapp
ps aux | grep myapp

# Check open files
lsof -p $(pidof myapp)

# Check network connections
netstat -tulpn | grep myapp

# Verify service file location
systemctl cat myapp

Best Practices

Security

  1. Run as non-root user
   [Service]
User=myappuser
Group=myappuser
  1. Enable security features
   [Service]
PrivateTmp=yes
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=yes
ReadOnlyPaths=/etc
  1. Limit resources
   [Service]
MemoryLimit=512M
LimitNOFILE=4096

Reliability

  1. Configure restart policy
   [Service]
Restart=always
RestartSec=5
StartLimitBurst=5
StartLimitIntervalSec=300
  1. Set timeout values
   [Service]
TimeoutStartSec=30
TimeoutStopSec=10
  1. Handle signals properly
  • Application should handle SIGTERM gracefully

  • Clean up resources on shutdown

Logging

  1. Use structured logging
  • Log to systemd journal (stdout/stderr)

  • Use appropriate log levels

  1. Configure log rotation
   [Service]
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
  1. Monitor logs
   # Set up log alerts if needed
journalctl -u myapp -f | grep -i error

Quick Reference Card

# Installation
sudo dpkg -i myapp_1.0.0_armhf.deb

# Service management
sudo systemctl start myapp # Start
sudo systemctl stop myapp # Stop
sudo systemctl restart myapp # Restart
sudo systemctl reload myapp # Reload config (if supported)
systemctl status myapp # Check status

# Boot configuration
sudo systemctl enable myapp # Auto-start on boot
sudo systemctl disable myapp # Don't auto-start
systemctl is-enabled myapp # Check if enabled

# Logging
journalctl -u myapp -f # Follow logs
journalctl -u myapp -n 50 # Last 50 lines
journalctl -u myapp --since today # Today's logs

# Service files
sudo systemctl daemon-reload # Reload after editing service file
systemctl cat myapp # View service file
systemctl show myapp # Show all properties

# Debugging
systemctl status myapp -l # Detailed status
journalctl -xe # System logs
systemd-analyze verify myapp.service # Validate service file

# Uninstallation
sudo systemctl stop myapp
sudo systemctl disable myapp
sudo dpkg -r myapp

Summary

Key Takeaways

  • Systemd integration provides standard Linux service management

  • Simple deployment using familiar systemd commands

  • Automatic restart on failure (if configured)

  • Provides resource limits and security hardening

  • Boot persistence through systemctl enable

    • Related Articles

    • Edge Gateway Main Page

      Edge Gateway Configuration & Development Your central hub for mastering Robustel Edge Gateways, tailored for developers and system integrators. From basic device configuration to advanced application development and third-party integration, find the ...
    • RobustOS Pro Third-Party Application Development Guide

      1. Quick Overview What is RobustOS Pro? RobustOS Pro is an embedded Linux distribution based on Debian 11 (bullseye), designed specifically to meet the demanding requirements of industrial IoT gateways, providing a high degree of customization and ...
    • NetworkManager Integration Guide

      1. Overview This document provides guidance for third-party application developers working on network-related development on RobustOS Pro devices. RobustOS Pro uses NetworkManager (NM) as its core network management service and provides two primary ...
    • How to Install Telit deviceWISE Asset Gateway on Robustel EG Series Gateways?

      Overview This guide provides step-by-step instructions for installing the Telit deviceWISE Asset Gateway software on a Robustel EG series gateway (e.g., EG5120). This installation allows you to leverage the powerful edge computing and Industrial IoT ...
    • How to Install CODESYS Control on a Robustel EG Series Gateway

      Overview This guide explains how to install the CODESYS Control runtime on a Robustel EG series gateway (such as the EG5120 or EG5200). By installing this runtime, you can transform your Robustel gateway into a powerful, industrial-grade PLC ...