Running TurboGears as a Windows Service

Status: User Contributed, thanks to Sean De La Torre

Prerequisites

The pywin32 package (previous known as win32all) with win32all docs avaiable at Mark Hammond's starship python site.

This must be installed before the Windows service functionality can be used.

Installation Instructions

1. Download service.py

service.py is an attachment for this page.

Note: this file does not have to be in the same directory as the TG application code.

2. Edit service.py

service.py contains a user's "USER EDIT SECTION" which may need to be edited. If service.py is located in the TG application's base directory, then the default values do not need to be changed. A description of each variable follows:

_svc_name_

Name of the service (used in the Windows registry).

Default: The capitalized name of the directory where the service.py file is located.

_svc_display_name_

Name that will be displayed in the Windows Services management console.

Default: The capitalized name of the directory where the service.py file is located.

code_dir

Base directory of the TG application code. This should be the same directory where the *appname*-start.py, dev.cfg, or prod.cfg files are located.

Default: The directory where the service.py file is located.

root_class

The fully qualified name of the main TG class. For example, if you were enabling the 20 Minute Wiki tutorial as a Windows service, then the fully qualified class name would be 'wiki20.controllers.Root'.

Default: *packagename*.controllers.Root

config_module

The name of the configuration module.

Default: *packagename*.config

log_dir

The location for the app's stdout and stderr log files.

Default: code_dir

3. Control your Service

Open a command prompt and navigate to the directory where service.py is located. Use the following commands to install/start/stop/remove your service:

service.py                        (Lists all available options)
service.py install                (Installs the service with a manual startup )
service.py --startup auto install (Installs the service with auto startup)

service.py start                  (Starts the service)
service.py stop                   (Stops the service)
service.py remove                 (Removes the service)

The service should now be accessible and controllable from the Window Services management console.

Notes

  • The autoreload functionality does not work when a CherryPy application is run as a Windows service (it crashes the service). Therefore, the code will disable the autoreload functionality before the server is started.

  • When the Python code runs as a Windows service, the current directory is automatically set to C:\<python-install-dir>\lib\site-packages\win32. service.py uses the code_dir value to reset the current directory to the base directory of the TG application.

  • The stdout and stderr output is redirected to two files (stdout.log and stderr.log). stdout and stderr must be redirected because when running as a service, they don't have a valid file to write to. So, when Windows attempts to flush stdout or stderr, the service crashes and the following entry is found in the Windows Event Application Logs:

    The instance's SvcRun() method failed
      File "C:\Python24\lib\site-packages\win32\lib\win32serviceutil.py", line 742, in SvcRun
        self.SvcDoRun()
      File "C:\Documents and Settings\<user>\Desktop\service.py", line 80, in SvcDoRun
        self.tg_init()
      File "C:\Documents and Settings\<user>\Desktop\service.py", line 115, in tg_init
        print 'try to crash the buffer over and over again...'
    exceptions.IOError: (9, 'Bad file descriptor')
  • The CherryPy site also lists a similar method of creating a CherryPy Windows service.

Troubleshooting

Use the Windows Event Viewer, the stdout, and the stderr log files to locate problems with your application.

If you need to have more than one service, for multiple applications, I found I needed to rename service.py, to a different file name for each application. Not doing this meant the services interfered with each other.

If your service stops when you log off Windows, try the following modification to the code:

#...snip...

# -- END USER EDIT SECTION
stop_event = win32event.CreateEvent(None, 0, 0, None)

def SvcDoRun(self):
    """ Called when the Windows Service runs. """

    self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
    self.tg_init()
    cherrypy.root = self.root()
    self.ReportServiceStatus(win32service.SERVICE_RUNNING)
    cherrypy.server.start(init_only=True)
    win32event.WaitForSingleObject(TGWindowsService.stop_event, win32event.INFINITE)

#...snip...

The comment feature has been disabled on this page due to heavy spamming. If you want to comment on the contents of this page, if you have questions, or want to report an error, please write to the TurboGears mailing list or open a documentation trac ticket.

Past comments:

localhost
2006-11-05 12:29:13

Great contribution! I've lost two days of my life trying to serve tg in
windows through apache and lighttpd. With this service, i did it in
5 minutes, thanks Sean!

localhost
2006-12-05 23:07:54

should run 'setup.py develop' to install the startup py script to PythonScripts dir. Otherwise the service can not start due to can not find the
module

localhost
2008-03-06 09:33:52

I've a TG project that uses a Windows COM server object, using the
comtypes package.
I've registered the COM object, added it to the system's PATH.
When I run the service in debug mode ('service.py debug'), everything
works fine, but when I run 'service.py start', the python code is unable
to find the COM object.

Anyone can help?

ChristopherArndt
2008-03-06 10:07:27

@localhost 2008-03-06 09:33:52: Please post your question to the mailing
list (see page "GettingHelp") where more people can help you. Comments
here are for comments on the documentation not for support requests.

localhost
2008-04-25 19:02:49

I want to thank you very much. This is really a great tip. You saved me a
lot of gray hairs, because the evil windows indeed crashes the tg-project
service after logoff.
Tried following tricks:
autoexnt.exe - runs a .bat file as a service containing
"python.exe c:/path/start-yourproject.py c:/path/prod.cfg"
instsrv.exe and srvany.exe - with the same command line as in the batch.
Both service methods crash after logoff with some error message:
python.exe ... memory could not be "read". Services are being reported as
running, but the python.exe process is dead.

mosi
http://www.mosi.sk

localhost
2008-06-12 16:27:21

When I install the service it doesn't keep the socket port setting

1.0/WindowsService (last edited 2009-10-22 10:02:00 by ChristopherArndt)