Run python script as daemon at boot time (Ubuntu)
Asked Answered
P

3

9

I've created small web server using werkzeug and I'm able to run it in usual python way with python my_server.py. Pages load, everything works fine. Now I want to start it when my pc boots. What's the easiest way to do that? I've been struggling with upstart but it doesn't seem to "live in a background" cuz after I execute start my_server I immediately receive kernel: [ 8799.793942] init: my_server main process (7274) terminated with status 1

my_server.py:

...
if __name__ == '__main__':
    from werkzeug.serving import run_simple
    app = create_app()
    run_simple('0.0.0.0', 4000, app)

upstart configuration file my_server.conf:

description "My service"
author  "Some Dude <[email protected]>"
start on runlevel [2345]
stop on runlevel [016]
exec /path/to/my_server.py
start on startup

Any Ideas how to make it work? Or any other better way to daemonize the script?

Update: I believe the problem lies within my_server.py. It doesn't seem to initiate the webserver (method run_simple()) in the first place. What steps should be taken to make .py file be run by task handler such as upstart?

  • Place shebang as first line #!/usr/bin/env python
  • Allow execution permissions chmod 755
  • Start the daemon with superuser rights (to be absolutely sure no permission restrictions prevents it from starting)
  • Make sure all python libraries are there!
  • Something else?

Solved: The problem was with missing python dependencies. When starting the script through task manager (e.g. upstart or start-stop-daemon) no errors are thrown. Need to be absolutely sure that pythonpath contains everything you need.

Phip answered 5/12, 2012 at 8:12 Comment(4)
Try runlevels 235 and form which user you run server you use 4000 priviliged ports which requires admin's rigths.Fatty
I run it as superuser and changing runlevel to 235 didn't help.Phip
Is it possible that dependency services of your app is not yet started? like some database?Embow
Yeap, a few libraries were missing. Thank you all for your effortPhip
B
17

In addition to gg.kaspersky method, you could also turn your script into a "service", so that you can start or stop it using:

$ sudo service myserver start
 * Starting system myserver.py Daemon                          [ OK ]
$ sudo service myserver status
 * /path/to/myserver.py is running
$ sudo service myserver stop
 * Stopping system myserver.py Daemon                          [ OK ]

and define it as a startup service using:

$ sudo update-rc.d myserver defaults

To do this, you must create this file and save it in /etc/init.d/.

#!/bin/sh -e

DAEMON="/path/to/myserver.py"
DAEMONUSER="myuser"
DAEMON_NAME="myserver.py"

PATH="/sbin:/bin:/usr/sbin:/usr/bin"

test -x $DAEMON || exit 0

. /lib/lsb/init-functions

d_start () {
        log_daemon_msg "Starting system $DAEMON_NAME Daemon"
        start-stop-daemon --background --name $DAEMON_NAME --start --user $DAEMONUSER --exec $DAEMON
        log_end_msg $?
}

d_stop () {
        log_daemon_msg "Stopping system $DAEMON_NAME Daemon"
        start-stop-daemon --name $DAEMON_NAME --stop --retry 5 --name $DAEMON_NAME
          log_end_msg $?
}

case "$1" in

        start|stop)
                d_${1}
                ;;

        restart|reload|force-reload)
                        d_stop
                        d_start
                ;;

        force-stop)
               d_stop
                killall -q $DAEMON_NAME || true
                sleep 2
                killall -q -9 $DAEMON_NAME || true
                ;;

        status)
                status_of_proc "$DAEMON_NAME" "$DAEMON" "system-wide $DAEMON_NAME" && exit 0 || exit $?
                ;;
        *)
                echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|force-stop|restart|reload|force-reload|status}"
                exit 1
                ;;
esac
exit 0

In this example, I assume you have a shebang like #!/usr/bin/python at the head of your python file, so that you can execute it directly.

Last but not least, do not forget to give execution rights to your python server and to the service script :

$ sudo chmod 755 /etc/init.d/myserver
$ sudo chmod 755 /path/to/mserver.py

Here's the page where I learned this originally (french).

Cheers.

Bali answered 5/12, 2012 at 10:21 Comment(2)
Good explanation on hove to create a deamon, but as my update suggest I believe something is wrong with script itself.Phip
@tvuillemin: This method was useful to me, but I need to debug my script... where can I find the standard and error output of my daemon script?Tingle
P
11

One simple way to do is using crontab:

$ crontab -e

A crontab file will appear for editing, write the line at the end:

@reboot python myserver.py

and quit. Now, after each reboot, the cron daemon will run your myserver python script.

Phylum answered 5/12, 2012 at 9:49 Comment(2)
Your suggestion might work, but I prefer to be able to start/stop/restart the daemon instead of rebooting the whole system in case of crash.Phip
You can check jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python, if you're interested in making your code a true daemon (I thought it already was, and you only needed to get it starting at boot time)Phylum
E
4

If you have supervisor service that starts at boot, write a supervisor service is much, much simpler.

You can even set autorestart if your program fails.

Embow answered 5/12, 2012 at 10:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.