I have a working server using Tornado now, according to the answer here: Python BaseHTTPServer and Tornado
I'd like to daemonize it. I have been reading over and over this daemon class example here, but I can't figure out how it wraps around my server code. Do I just put all the code from __main__
in the run()
that I override?
How do I subclass it also if it's in another file? Make sure it's in the same directory and using it's filename without .py extension to import?
I'm just looking for the simplest way to run my python web server script with nothing more than a simple call such as ./startserver.sh
(for example, if I was to use a bash script) and have it run in the background with no nohup.out file and all stdout and stderr redirected to log files.
Let's keep it simple. Project tree:
$ tree
.
├── daemon.py
├── main.py
├── server.py
└── __init__.py
daemon.py
is a Daemon class from http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/, server.py
is threaded version of code from Python BaseHTTPServer and Tornado, __init__.py
is an empty file which allows us to import code from other files in directory. main.py
is:
#!/usr/bin/env python
import sys, time, threading
from daemon import Daemon
from server import run_tornado, run_base_http_server
class ServerDaemon(Daemon):
def run(self):
threads = [
threading.Thread(target=run_tornado),
threading.Thread(target=run_base_http_server)
]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
if __name__ == "__main__":
daemon = ServerDaemon('/tmp/server-daemon.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)
Run it with:
$ python main.py start
For first version from Python BaseHTTPServer and Tornado change
if __name__ == '__main__':
to def myfun():
and call it from run()
method of Daemon
subclass.
Try using the supervisor
daemon package on Linux. It lets you daemonize things easily.
For Ubuntu: sudo apt-get install supervisor
Create a conf.d
file:
cd /etc/supervisor/conf.d/
vim pyhttpd.conf
Inside your pyhttpd.conf
:
[program:pyhttpd]
directory=/path/to/project
environment=ENV_VAR=ENV_VAL,ENV_VAR2=ETC
command=startserver.sh
autostart=true
autorestart=true
Finally, update supervisor
with the new config:
supervisorctl update
It should be started for you, and will now run whenever you boot up.
These commands are also available:
supervisorctl stop pyhttpd
supervisorctl start pyhttpd
supervisorctl restart pyhttpd
stdout
and stderr
are logged to the /var/log/supervisor/
directory.