11 # SITES = [(sitename, application_list)]
12 # application_list = [application_name, (application_name, command, ...)]
13 # Here, sitename is the name of the site. This folder name should exist below ROOT_DIR and
14 # is also used below SOCKET_DIR. The site name is also translated to a user and
15 # group name by replacing dots by dashes and prepending USER_PREFIX and
18 # application_list specifies the applications to start for this site. These can
19 # be generic (when only application_name is given), in which case the command
20 # is looked up in APPLICATIONS using the application_name. For a site-specific
21 # application, command is the command that should be run. It will be prefixed
22 # with the site's root dir, if is not an absolute path.
26 ('stderr.nl', ['php', ('trac', 'applications/trac/trac.fcgi')]),
27 # ('stdin.nl', ['php']),
28 ('stdout.nl', ['php']),
29 ('ninniach.nl', ['php']),
30 # ('evolution-events.nl', ['php']), #, ('xerxes', 'applications/xerxes/manage.py runfcgi'), ('wipi', 'applications/wipi/wipi.fcgi')]),
31 # ('stdio.flexvps.nl', ['php']),
32 # ('foresightsecurity.nl', ['php']),
35 # Generic applications that can be run for any site
36 # Maps application_name to application_command. application_command will be
37 # prefixed with the site's root dir, if it is not an absolute path.
38 APPLICATIONS={"php": "/usr/bin/php-cgi"}
40 # Kill these procs before starting new ones. Only processes of these names that
41 # are run by the sites in SITES are killed. This is a bit hackish, we should
42 # really be using pidfiles...
43 KILL_PROCS=['php-cgi', 'manage.py']
45 ## ABSOLUTE path to the spawn-fcgi binary
46 SPAWNFCGI="/usr/bin/spawn-fcgi"
48 ## Dir in which to create the UNIX sockets to listen on
49 SOCKET_DIR="%s/var/fcgi" % (ROOT_DIR)
51 ## number of PHP children to spawn
54 ## maximum number of requests a single PHP process can serve before it is restarted
55 PHP_FCGI_MAX_REQUESTS=1000
57 # The user to run as, will be prefixed to the sitename
59 # The group to run as.
60 SCRIPT_GROUP="httpd-users"
61 # The group that should be able to use the sockets created
62 HTTPD_GROUP="www-data"
64 # Will be postfixed to the site's root and exported in the PHPRC variable.
67 #### END OF CONFIG ####
69 for (site, apps) in SITES:
70 site_name = re.sub('\.', '-', site)
72 ## switch to the following user / group
73 user_id = "%s%s" % (USER_PREFIX, site_name)
76 site_dir = os.path.join(ROOT_DIR, site)
77 socket_dir = os.path.join(SOCKET_DIR, site_name)
79 # Pass the site dir to all fastcgi processes
80 os.environ['SITE_DIR'] = site_dir
83 raise Exception("Site dir does not exist: %s" % (site_dir))
86 # Kill existing processes first
87 for procname in KILL_PROCS:
88 os.system('killall --user %s %s' % (user_id, procname))
91 if os.path.exists(socket_dir):
92 shutil.rmtree(socket_dir)
94 # Create dir for sockets. Make owning group root and set group write
95 # permissions, so the mask field in the acl will not block out anything.
96 os.makedirs(socket_dir)
97 os.chown(socket_dir, pwd.getpwnam(user_id)[2], grp.getgrnam(HTTPD_GROUP)[2])
98 #os.chmod(socket_dir, stat.S_IRWXU)
101 # Unpack app tuple or lookup app command in APPLICATIONS
102 if isinstance(app, tuple):
104 (app_name, app_command) = app
106 raise Exception("Wrong number of elements in site tuple: %s", app)
109 app_command = APPLICATIONS[app_name]
111 # Prefix with site dir if not an absolute path
112 if not os.path.isabs(app_command):
113 app_command = os.path.join(site_dir, app_command)
115 # Create socket filename
116 socket = os.path.join(socket_dir, app_name)
119 # TODO: Wrap this in env to clear up the environment
120 spawnfcgi = '%s -s "%s" -u "%s" -g "%s"' % (SPAWNFCGI, socket, user_id, SCRIPT_GROUP)
121 fcgiapp = ' -- %s' % (app_command)
123 if app_name == 'php':
124 os.environ['PHP_FCGI_MAX_REQUESTS'] = str(PHP_FCGI_MAX_REQUESTS)
125 phprc = os.path.join(site_dir, PHPRC_DIR, 'php.ini')
126 if os.path.exists(phprc):
127 #os.environ['PHPRC'] = phprc
128 fcgiapp += ' -c %s' % (phprc)
129 spawnfcgi += ' -C %s' % (PHP_FCGI_CHILDREN)
132 print spawnfcgi + fcgiapp
133 os.system(spawnfcgi + fcgiapp)
135 # Ensure www-data can write to the socket :-S
136 # Spawn-fcgi explicitely chmods the socket after creation, very
138 os.chmod(socket, stat.S_IRWXU | stat.S_IRWXG)