Flask应用部署至Google Cloud Run遇404错误(本地正常)求助
解决Cloud Run部署Flask应用出现404错误的问题
我尝试使用gunicorn将Flask应用部署到Google Cloud Run,但在Cloud Run中访问'/'页面时出现如下404错误(本地运行正常):
Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1453, in dispatch_request self.raise_routing_exception(req) File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1436, in raise_routing_exception raise request.routing_exception File "/usr/local/lib/python3.7/site-packages/flask/ctx.py", line 286, in match_request self.url_adapter.match(return_rule=True) File "/usr/local/lib/python3.7/site-packages/werkzeug/routing.py", line 1581, in match raise NotFound() werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
我的代码文件
app.py关键代码
... def create_app(settings_override=None): """ Create a Flask application using the app factory pattern. :param settings_override: Override settings :return: Flask app """ app = Flask(__name__, instance_relative_config=True) app.config.from_object("config.settings") app.config.from_pyfile("settings.py", silent=True) if settings_override: app.config.update(settings_override) app.register_blueprint(page) app.register_blueprint(contact) extensions(app) middleware(app) error_templates(app) # exception_handler(app) template_processors(app) return app ... def middleware(app): """ Register 0 or more middleware (mutates the app passed in). :param app: Flask application instance :return: None """ # Swap request.remote_addr with the real IP address even if behind a proxy. app.wsgi_app = ProxyFix(app.wsgi_app) return None
Dockerfile内容
... # Expose port 8000 EXPOSE 8000 ENV PORT 8000 CMD gunicorn -c "python:config.gunicorn" "snakeeyes.app:create_app()" --timeout 1000
config/gunicorn.py内容
# -*- coding: utf-8 -*- bind = "0.0.0.0:8000" accesslog = "-" access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" in %(D)sµs'
排查与解决方法
1. 确保端口与Cloud Run环境匹配
Cloud Run会通过$PORT环境变量指定容器要监听的端口,虽然你已经在Dockerfile中设置了ENV PORT 8000,但gunicorn配置里硬编码了端口。建议改为动态读取环境变量,避免潜在的不一致:
修改config/gunicorn.py:
import os bind = f"0.0.0.0:{os.environ.get('PORT', 8000)}"
或者直接在CMD命令中指定端口:
CMD gunicorn -c "python:config.gunicorn" --bind "0.0.0.0:$PORT" "snakeeyes.app:create_app()" --timeout 1000
2. 检查蓝图路由配置
你注册了page和contact两个蓝图,但未提供蓝图内部的路由定义。请确认:
page蓝图中是否包含根路径路由:@page.route('/')- 注册蓝图时是否误加了前缀,比如
app.register_blueprint(page, url_prefix='/some-path'),这种情况下根路径/会没有对应的处理函数。
3. 验证配置文件的差异
本地与Cloud Run环境的配置可能不同,检查config.settings或instance/settings.py中是否设置了APPLICATION_ROOT,该配置会为所有路由添加前缀,导致/无法匹配。如果不需要该配置,直接移除即可。
4. 确认gunicorn启动的应用实例正确
在本地构建容器并运行,模拟Cloud Run环境测试:
docker build -t flask-app . docker run -p 8000:8000 flask-app
访问http://localhost:8000,如果也出现404,说明问题出在应用本身而非Cloud Run配置,进一步排查蓝图注册或路由定义。
5. 调整ProxyFix参数
Cloud Run会转发请求头,默认的ProxyFix可能无法正确处理所有头信息,修改middleware函数:
from werkzeug.middleware.proxy_fix import ProxyFix def middleware(app): app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1) return None
确保Flask能正确识别请求的原始URL,避免路由匹配错误。
内容的提问来源于stack exchange,提问作者Filipe Ferminiano
相关产品推荐
相关产品推荐

