How to make Python script run as service?

Solution 1:

I use this code to daemonize my applications. It allows you start/stop/restart the script using the following commands.

python myscript.py start
python myscript.py stop
python myscript.py restart

In addition to this I also have an init.d script for controlling my service. This allows you to automatically start the service when your operating system boots-up.

Here is a simple example to get your going. Simply move your code inside a class, and call it from the run function inside MyDeamon.

import sys
import time

from daemon import Daemon


class YourCode(object):
    def run(self):
        while True:
            time.sleep(1)


class MyDaemon(Daemon):
    def run(self):
        # Or simply merge your code with MyDaemon.
        your_code = YourCode()
        your_code.run()


if __name__ == "__main__":
    daemon = MyDaemon('/tmp/daemon-example.pid')
    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            daemon.start()
        elif 'stop' == sys.argv[1]:
            daemon.stop()
        elif 'restart' == sys.argv[1]:
            daemon.restart()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)

Upstart

If you are running an operating system that is using Upstart (e.g. CentOS 6) - you can also use Upstart to manage the service. If you use Upstart you can keep your script as is, and simply add something like this under /etc/init/my-service.conf

start on started sshd
stop on runlevel [!2345]

exec /usr/bin/python /opt/my_service.py
respawn

You can then use start/stop/restart to manage your service.

e.g.

start my-service
stop my-service
restart my-service

A more detailed example of working with upstart is available here.

Systemd

If you are running an operating system that uses Systemd (e.g. CentOS 7) you can take a look at the following Stackoverflow answer.

Solution 2:

I offer two recommendations:

supervisord

1) Install the supervisor package (more verbose instructions here):

sudo apt-get install supervisor

2) Create a config file for your daemon at /etc/supervisor/conf.d/flashpolicyd.conf:

[program:flashpolicyd]
directory=/path/to/project/root
environment=ENV_VARIABLE=example,OTHER_ENV_VARIABLE=example2
command=python flashpolicyd.py
autostart=true
autorestart=true

3) Restart supervisor to load your new .conf

supervisorctl update
supervisorctl restart flashpolicyd

systemd (if currently used by your Linux distro)

[Unit]
Description=My Python daemon

[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/project/main.py
WorkingDirectory=/opt/project/
Environment=API_KEY=123456789
Environment=API_PASS=password
Restart=always
RestartSec=2

[Install]
WantedBy=sysinit.target

Place this file into /etc/systemd/system/my_daemon.service and enable it using systemctl daemon-reload && systemctl enable my_daemon && systemctl start my_daemon --no-block.

To view logs:

systemctl status my_daemon