Python Daemon Packaging Best Practices

后端 未结 10 1437
没有蜡笔的小新
没有蜡笔的小新 2021-01-30 09:48

I have a tool which I have written in python and generally should be run as a daemon. What are the best practices for packaging this tool for distribution, particularly how sho

相关标签:
10条回答
  • 2021-01-30 09:53

    correct me if wrong, but I believe the question is how to DEPLOY the daemon. Set your app to install via pip and then make the entry_point a cli(daemon()). Then create an init script that simply runs $app_name &

    0 讨论(0)
  • 2021-01-30 09:54

    I can't remember where I downloaded it... but this is the best daemonizing script that I've found. It works beautifully (on Mac and Linux.) (save it as daemonize.py)

    import sys, os
    def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
        # Perform first fork.
        try:
            pid = os.fork( )
            if pid > 0:
                sys.exit(0) # Exit first parent.
        except OSError, e:
            sys.stderr.write("fork #1 failed: (%d) %sn" % (e.errno, e.strerror))
            sys.exit(1)
        # Decouple from parent environment.
        os.chdir("/")
        os.umask(0)
        os.setsid( )
        # Perform second fork.
        try:
            pid = os.fork( )
            if pid > 0:
                sys.exit(0) # Exit second parent.
        except OSError, e:
            sys.stderr.write("fork #2 failed: (%d) %sn" % (e.errno, e.strerror))
            sys.exit(1)
        # The process is now daemonized, redirect standard file descriptors.
        for f in sys.stdout, sys.stderr: f.flush( )
        si = file(stdin, 'r')
        so = file(stdout, 'a+')
        se = file(stderr, 'a+', 0)
        os.dup2(si.fileno( ), sys.stdin.fileno( ))
        os.dup2(so.fileno( ), sys.stdout.fileno( ))
        os.dup2(se.fileno( ), sys.stderr.fileno( ))
    

    In your script, you would simply:

    from daemonize import daemonize
    daemonize()
    

    And you can also specify places to redirect the stdio, err, etc...

    0 讨论(0)
  • 2021-01-30 09:54

    On Linux systems, the system's package manager (Portage for Gentoo, Aptitude for Ubuntu/Debian, yum for Fedora, etc.) usually takes care of installing the program including placing init scripts in the right places. If you want to distribute your program for Linux, you might want to look into bundling it up into the proper format for various distributions' package managers.

    This advice is obviously irrelevant on systems which don't have package managers (Windows, and Mac I think).

    0 讨论(0)
  • 2021-01-30 09:55

    This blog entry made it clear for me that there are actually two common ways to have your Python program run as a deamon (I hadn't figured that out so clearly from the existing answers):

    There are two approaches to writing daemon applications like servers in Python.

    • The first is to handle all the tasks of sarting and stopping daemons in Python code itself. The easiest way to do this is with the python-daemon package which might eventually make its way into the Python distribution.

    Poeljapon's answer is an example of this 1st approach, although it doesn't use the python-daemon package, but links to a custom but very clean python script.

    • The other approach is to use the tools supplied by the operating system. In the case of Debain, this means writing an init script which makes use of the start-stop-daemon program.

    Ali Afshar's answer is a shell script example of the 2nd approach, using the start-stop-daemon.

    The blog entry I quoted has a shell script example, and some additional details on things such as starting your daemon at system startup and restarting your daemon automatically when it stopped for any reason.

    0 讨论(0)
  • 2021-01-30 10:02

    Check the Ben Finney's daemon module. He has started to write a PEP targeting python 3.X:

    http://www.python.org/dev/peps/pep-3143/

    But an implementation is already available here :

    http://pypi.python.org/pypi/python-daemon/

    0 讨论(0)
  • 2021-01-30 10:03

    There are many snippets on the internet offering to write a daemon in pure python (no bash scripts)

    http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ looks clean...

    If you want to write your own,
    the principle is the same as with the bash daemon function.

    Basically:

    On start:

    • you fork to another process
    • open a logfile to redirect your stdout and stderr
    • Save the pid somewhere.

    On stop:

    • You send SIGTERM to the process with pid stored in your pidfile.
    • With signal.signal(signal.SIGTERM, sigtermhandler) you can bind a stopping procedure to the SIGTERM signal.

    I don't know any widely used package doing this though.

    0 讨论(0)
提交回复
热议问题