使用Gunicorn启动Flask应用遭遇两难困境,求正确用法
问题
我需要使用Gunicorn运行Flask应用,但Gunicorn不会执行代码中if __name__ == '__main__':这部分逻辑。我的Flask应用代码如下:
import sys #... app = Flask(__name__) CORS(app) # Enable CORS for all routes @app.route('/api/myapi', methods=['POST']) def myapi(): #... @app.after_request def add_header(response): response.headers['Access-Control-Allow-Origin'] = '*' response.headers['Access-Control-Allow-Headers'] = 'Content-Type' return response #if __name__ == '__main__': # print('Starting APP server...') # context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) # context.load_cert_chain('/etc/letsencrypt/live/mywebsite.com/cert.pem', # '/etc/letsencrypt/live/mywebsite.com/privkey.pem') # app.run(host='mywebsite.com', port=5000, ssl_context=context)
取消注释if __name__ == '__main__':块后,Flask会以开发模式正常运行,但这不是我想要的。于是我用了单独的wsgi.py文件,内容如下:
from vicky_server_ionos_8 import app if __name__ == '__main__': app.run()
之后执行命令:
gunicorn --bind 88.888.888.888:5000 wsgi:app
现在陷入困境:为了避免开发模式必须用Gunicorn,但Gunicorn似乎忽略if __name__ == '__main__':块,导致app.run()没执行,应用启动不了。我以为Gunicorn会自动启动应用,但实际不是,请问问题出在哪?怎么正确用Gunicorn?
解决方案
核心问题:误解Gunicorn的工作逻辑
Gunicorn作为生产级WSGI服务器,不需要调用app.run()。它会直接导入wsgi模块中的app对象(即你的Flask实例),通过WSGI协议驱动应用,完全绕开if __name__ == '__main__':判断——因为Gunicorn导入wsgi模块时,模块的__name__是wsgi而非__main__,所以该代码块不会执行,也没必要执行。
正确配置步骤
简化wsgi.py文件
删除多余的if __name__ == '__main__':代码块,仅保留Flask实例的导入:from vicky_server_ionos_8 import app这样Gunicorn就能直接获取所需的
app对象,无需额外启动逻辑。配置SSL(如果需要HTTPS)
原代码中if __name__ == '__main__':里的SSL配置无法直接复用,需在Gunicorn启动命令中指定证书和密钥:gunicorn --bind 88.888.888.888:5000 --certfile /etc/letsencrypt/live/mywebsite.com/cert.pem --keyfile /etc/letsencrypt/live/mywebsite.com/privkey.pem wsgi:app生产环境更推荐用Nginx等反向代理处理SSL,Gunicorn仅负责处理HTTP请求,这种架构更稳定安全。
验证应用启动
执行上述Gunicorn命令后,服务器会自动监听指定IP和端口,无需手动调用app.run()。可通过访问https://88.888.888.888:5000/api/myapi测试应用是否正常运行。
额外提示
- Flask自带的
app.run()是开发服务器,仅适合开发场景,生产环境必须使用Gunicorn、uWSGI这类专业WSGI服务器。 - Gunicorn的核心逻辑就是加载WSGI应用实例(你的
app对象),只要wsgi模块能正确导出app,启动命令指向该实例即可正常运行。
内容的提问来源于stack exchange,提问作者Diego

