Skip to content

A Step-by-Step Guide to Running Python Scripts as Services

Need to continuously run Python scripts for ongoing automation and scheduling? Configuring scripts as long-running services can be a robust solution.

In this comprehensive, 2200+ word guide, we’ll walk through the steps to run Python scripts as system services on both Linux and Windows.

We’ll cover:

  • Key benefits of using services for automation
  • How Linux systemd and Windows Service Control Manager work
  • Configuring systemd units to manage Python services
  • Building Windows services with pywin32
  • Simplifying Windows services with NSSM
  • Tips for security, logging, and troubleshooting

Follow along and you’ll gain the knowledge to configure your Python automation scripts to run reliably as services on any system!

Why Run Python Scripts as Services?

Running scripts via python script.py works fine for one-off jobs. But for recurring automation tasks, dedicated services provide important benefits:

Scheduled Execution

Services run continuously in the background rather than needing manual starts. This enables python scripts to be run on schedules.

Automatic Restarts

Crashed or stopped services can restart automatically. This results in resilient automation.

Centralized Control

Tools like systemd and the Windows Service Control Manager provide one place to monitor, configure, and manage services.

Security

Services can run under isolated users and permissions for reduced risk.

Common examples of Python scripts that work well as services:

  • Web scraping scripts that need to run regularly to fetch updated data
  • Machine learning model training that is resource-intensive if run too often
  • Cron-style scheduled jobs like cleaning temp files or synchronizing caches

Next, we‘ll look at how Linux systemd and Windows Service Control Manager enable running scripts as managed services.

An Introduction to Service Managers

Modern operating systems come equipped with service managers that handle launching, monitoring, and stopping services.

systemd

The most widely used service manager on Linux is systemd. It acts as the init system for most major distros like Ubuntu, Debian, RHEL.

systemd is powerful not only because it handles service processes, but also because it manages system startup, devices, sockets, timers, and more.

Key capabilities provided by systemd for services:

  • Service lifecycle management – start, stop, restart
  • Configurable restart policies – always restart, on-failure, etc
  • Resource limitation – set memory, CPU, IO limits
  • Log integration with journald
  • Dependency ordering – start service X after Y

Services are configured by creating unit files, typically stored in /etc/systemd/system.

Windows Service Control Manager

This is the service manager built into Windows for handling long-running backend processes. It provides similar capabilities to systemd, such as:

  • Automated startup of services
  • Monitoring service state – running, stopped, etc
  • Centralized control for starting, stopping services
  • Configurable restart settings and recovery actions

Services register themselves with the SCM and provide lifecycle event handlers. The net command is used to manage services.

Now that we‘ve seen how Linux and Windows enable services, let‘s walk through configuring Python scripts on each!

Step-by-Step: Creating systemd Services for Python

On Linux, we can leverage systemd to run Python scripts as managed services. This offers standardized configs and tight integration with the OS.

Let‘s look at how to configure a Python script as a systemd service on Linux:

  1. First, create a Python script with the logic you want to run continuously:

     import requests
    
     def main():
         response = requests.get("https://www.example.com")
         print(response.status_code)
    
     if __name__ == "__main__":
         main() 
  2. Next, create a systemd service file like /etc/systemd/system/myscript.service:

     [Unit]
     Description=My Script Service
    
     [Service]
     ExecStart=/usr/bin/python3 /opt/scripts/myscript.py 
     Restart=on-failure
     RestartSec=10
    
     [Install]
     WantedBy=multi-user.target

    Let‘s explain some key points:

    • The [Unit] section provides metadata like a description
    • [Service] defines the script path for ExecStart and restart policy
    • [Install] says to start on system boot as a multi-user service
  3. Now reload systemd and start the service:

     sudo systemctl daemon-reload
     sudo systemctl start myscript.service
  4. Check status with systemctl status myscript or view logs via journalctl -u myscript

And we have a Python service managed by systemd! The script will run continuously, logging to journald, and auto-restart on failures.

Some more tips for robust Python systemd services:

  • Use ExecStartPre and ExecStartPost to add prep/cleanup logic
  • Set resource limits under [Service] like MemoryMax=200M
  • Make the service a template file at /etc/systemd/system/[email protected] for multiple instances

Overall systemd provides a powerful way to deploy Python scripts as managed Linux services.

Creating Windows Services in Python with pywin32

On Windows, we can use the pywin32 library to directly create services using Python.

The steps are:

  1. Structure the Python script to handle service commands
  2. Subclass win32serviceutil.ServiceFramework
  3. Implement lifecycle event handlers like SvcDoRun
  4. Install and run the service

Here is an example Python Windows service:

import win32serviceutil
import win32service

class PySvc(win32serviceutil.ServiceFramework):
    _svc_name_ = "PyService"
    _svc_display_name_ = "Python Sample Service"

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)

    def SvcDoRun(self):
        self.ReportServiceStatus(win32service.SERVICE_RUNNING) 
        # service logic goes here

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOPPED)
        # shutdown logic goes here 

if __name__ == ‘__main__‘: 
    win32serviceutil.HandleCommandLine(PySvc)

To install:

pyinstaller --onefile pyservice.py
pyservice.exe --install  
net start PyService

This allows full control over the Python service logic. But the pywin32 APIs can be verbose and low-level.

Simplifying Windows Services with NSSM

An alternative to pywin32 for running Python scripts as Windows services is the NSSM – the Non-Sucking Service Manager.

NSSM makes it very easy to wrap executables as Windows services with just a few commands:

nssm install MyService C:\Python\myscript.exe
nssm set MyService AppParameters "--log=C:\logs\mylog.txt"
nssm start MyService

Advantages of using NSSM over pywin32:

  • No need to write Python service classes
  • Easily pass arguments with AppParameters
  • Management via concise commands like nssm [action] [service]
  • Monitor stdout/stderr, set working directory, etc

So if you just need to quickly run a Python script as a Windows service, definitely give NSSM a try!

Securing and Troubleshooting Python Services

When running Python scripts as persistent services, we also need to consider security, logging, and troubleshooting.

Here are some tips:

  • Run under a limited user – Don‘t give the service account more permissions than necessary
  • Enable logging – For systemd, integrate with journald. For Windows, redirect to a log file
  • Limit restart attempts – In case of crashes, don‘t restart endlessly
  • Sandbox the environment – Use virtual environments and AppArmor profiles
  • Review logs – journalctl and event viewer are key troubleshooting tools
  • Monitor processes – Check systemctl status or task manager for resource usage
  • Use service management commandssystemctl, nssm, and net start/stop services
  • Know how to disable services – Run systemctl disable or sc config [Service] start= disabled

Taking these best practices into account will help keep Python services running smoothly and securely.

Alternative Service Managers

While systemd and Windows SCM are native solutions, there are also some cross-platform alternatives:

  • supervisord – Popular for managing Python and Go services
  • pm2 – Node.js service manager with a large ecosystem

Both allow configuring services in ini-style config files and provide features like monitoring and log aggregation.

For simpler scripts, systemd or NSSM may be preferable. But supervisord and pm2 are worth evaluating if you need broader language support.

Key Takeaways

We‘ve covered a lot of ground on running Python scripts as managed services! Here are some key tips to remember:

  • Use systemd on Linux and SCM on Windows for native OS integration
  • Familiarize yourself with journald and event viewer for logging
  • systemd uses unit files, SCM uses registry keys
  • For Windows, NSSM makes deployment easy
  • Control service lifecycles via systemctl, net stop, etc
  • Follow security best practices like limited accounts
  • Set restart policies to balance availability and recoverability

Whether you‘re on Linux or Windows, you now have the knowledge to configure Python scripts as services! Automating recurring tasks with Python is now easy and reliable.

Tags:

Join the conversation

Your email address will not be published. Required fields are marked *