Skip to main content
 首页 » 编程设计

python之设置 webhook 以重新启动 django 服务器的 apache 的最佳方法

2025年05月04日20tintown

我首先尝试使用 django,然后使用 django-webhooks 来调用重启服务器的 shell 脚本。这没有用,因为当调用服务器重启时网页挂起,因为 django 被重新加载。

然后我单独使用fastcgi和python创建了一个调用shell脚本的URL。我知道 python 脚本在服务器上运行时有效,但在从 URL 运行时无效。

Apache 设置为:

<VirtualHost *:80> 
    ServerName webhooks.myserver.com 
 
    DocumentRoot /home/ubuntu/web/common/www 
    <Directory /> 
        Options FollowSymLinks +ExecCGI 
        AllowOverride All 
    </Directory> 
 
    <Files post.py> 
        SetHandler fastcgi-script 
    </Files> 
 
    FastCgiServer /home/ubuntu/web/common/www/post.py -processes 2 -socket /tmp/fcgi.sock 
</VirtualHost>

apache调用的python代码为:

#!/usr/bin/python 
 
import fcgi, warnings, os, subprocess 
 
BASE_DIR = os.getcwd() 
 
def app(environ, start_response): 
    cmd = "sudo %s/../deploy/postwebhook.sh >> /var/log/votizen/webhooks_run.log 2>> /var/log/votizen/webhooks_error.log &" % BASE_DIR 
    warnings.warn("Running cmd=%s" % cmd) 
    bufsize = -1 
    PIPE = subprocess.PIPE 
    subprocess.Popen(cmd, shell=isinstance(cmd, basestring), 
                         bufsize=bufsize, stdin=PIPE, stdout=PIPE, 
                         stderr=PIPE, close_fds=True) 
 
    warnings.warn("Post deployment webhook completed") 
 
    start_response('200 OK', [('Content-Type', 'text/html')]) 
    return('Hello World!') 
 
fcgi.WSGIServer(app, bindAddress = '/tmp/fcgi.sock').run()

shell脚本是:

#!/bin/bash 
 
# restart the apache server 
echo ' ' 
echo 'post webhooks started' 
date '+%H:%M:%S %d-%m-%y' 
apache2ctl -t; sudo /etc/init.d/apache2 stop; sudo /etc/init.d/apache2 start 
 
# todo: check if apache failed 
 
# copy media files for apps 
echo "moving SC to S3" 
python /home/ubuntu/web/corporate/manage.py sync_media_s3 -p sc 
 
date '+%H:%M:%S %d-%m-%y' 
echo 'post webhooks completed'

我在 apache 日志中没有看到任何错误,访问日志显示正在调用触发 URL。但是,我只在重新启动后第一次调用 URL 时看到 python 警告,它实际上从未重新启动服务器。

请您参考如下方法:

我正在使用 webfaction,以下脚本适用于我:

import time 
import os 
 
BASE_DIR = "/path/to/your/app/" 
 
def stopit(app): 
    os.popen( os.path.join(BASE_DIR, "apache2", "bin", "stop") ) 
 
def startit(app): 
    os.popen( os.path.join(BASE_DIR, "apache2", "bin", "start") ) 
 
def restart(app): 
    stopit(app) 
    time.sleep(1) 
    startit(app) 

“停止”脚本如下所示:

#!/usr/local/bin/python 
import os 
lines = os.popen('ps -u username -o pid,command').readlines() 
running = False 
for line in lines: 
    if '/path/to/app/apache2/conf/httpd.conf' in line: 
        running = True 
        proc_id = line.split()[0] 
        os.system('kill %s 2> /dev/null' % proc_id) 
if not running: 
    print "Not running" 
else: 
    print "Stopped" 

“启动”脚本:

/path/to/app/apache2/bin/httpd -f /path/to/app/apache2/conf/httpd.conf