How to make Python script run as service?

PythonLinuxCentos

Python Problem Overview


I want to run a python script in a CENTOS server:

#!/usr/bin/env python
import socket
try:    
	import thread 
except ImportError:
	import _thread as thread #Py3K changed it.
class Polserv(object):
	def __init__(self):
		self.numthreads = 0
		self.tidcount   = 0
		self.port       = 843
		self.sock       = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		self.sock.bind(('100.100.100.100', self.port))
		self.sock.listen(5)
	def run(self):
		while True:
			thread.start_new_thread(self.handle, self.sock.accept()) 
	def handle(self,conn,addr):
		self.numthreads += 1
		self.tidcount   += 1
		tid=self.tidcount
		while True:
			data=conn.recv(2048)
			if not data:
				conn.close()
				self.numthreads-=1
				break
			#if "<policy-file-request/>\0" in data:
			conn.sendall(b"<?xml version='1.0'?><cross-domain-policy><allow-access-from domain='*' to-ports='*'/></cross-domain-policy>")
			conn.close()
			self.numthreads-=1
			break
		#conn.sendall(b"[#%d (%d running)] %s" % (tid,self.numthreads,data) )
Polserv().run()

Im using $ python flashpolicyd.py and it works fine... The question is: How to keep this script running even after I close the terminal(console)?

Python Solutions


Solution 1 - Python

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 - Python

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

Solution 3 - Python

My non pythonic approach would be using & suffix. That is:

python flashpolicyd.py &

To stop the script

killall flashpolicyd.py

also piping & suffix with disown would put the process under superparent (upper):

python flashpolicyd.pi & disown

Solution 4 - Python

first import os module in your app than with use from getpid function get pid's app and save in a file.for example :

import os
pid = os.getpid()
op = open("/var/us.pid","w")
op.write("%s" % pid)
op.close()

and create a bash file in /etc/init.d path: /etc/init.d/servername

PATHAPP="/etc/bin/userscript.py &"
PIDAPP="/var/us.pid"
case $1 in 
        start)
                echo "starting"
                $(python $PATHAPP)
        ;;
        stop)
                echo "stoping"
                PID=$(cat $PIDAPP)
                kill $PID
        ;;

esac

now , u can start and stop ur app with down command:

service servername stop service servername start

or

/etc/init.d/servername stop /etc/init.d/servername start

Solution 5 - Python

for my script of python, I use...

To START python script :

start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --exec $DAEMON

To STOP python script :

PID=$(cat $PIDFILE)
kill -9 $PID
rm -f $PIDFILE

P.S.: sorry for poor English, I'm from CHILE :D

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFilipe TagliacozziView Question on Stackoverflow
Solution 1 - PythoneanderssonView Answer on Stackoverflow
Solution 2 - PythonpztrickView Answer on Stackoverflow
Solution 3 - PythonpsukysView Answer on Stackoverflow
Solution 4 - PythonArsalanView Answer on Stackoverflow
Solution 5 - PythonRodrigo NavarreteView Answer on Stackoverflow