部署Docker应用至Google Cloud Run(端口8000)出现404错误求助
部署应用到Google Cloud Run后访问出现404错误(错误页面截图如下),但应用在本地通过docker-compose运行完全正常。

docker-compose.yml配置
version: '2' services: redis: image: 'redis:3.0-alpine' command: redis-server --requirepass devpassword volumes: - 'redis:/var/lib/redis/data' ports: - '6379:6379' website: build: . command: > gunicorn -c "python:config.gunicorn" --reload "snakeeyes.app:create_app()" env_file: - '.env' volumes: - '.:/snakeeyes' ports: - '8000:8000' celery: build: . command: celery worker -l info -A snakeeyes.blueprints.contact.tasks env_file: - '.env' volumes: - '.:/snakeeyes' volumes: redis:
Dockerfile配置
FROM python:3.7.5-slim-buster RUN apt-get update && apt-get install -qq -y \ build-essential libpq-dev --no-install-recommends ENV INSTALL_PATH /snakeeyes RUN mkdir -p $INSTALL_PATH WORKDIR $INSTALL_PATH COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . RUN pip install --editable . # CMD gunicorn -b 0.0.0.0:8000 --access-logfile - "snakeeyes.app:create_app()" CMD gunicorn -c "python:config.gunicorn" "snakeeyes.app:create_app()"
已将Cloud Run容器端口设置为8000并允许公网请求,尝试执行以下命令:
curl -v https://xxx-q42lz4rc5a-uc.a.run.app/
返回结果:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>404 Not Found</title> <h1>Not Found</h1> <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
Cloud Run请求日志:
{ httpRequest: { latency: "0.003104020s" protocol: "HTTP/1.1" remoteIp: "189.102.84.133" requestMethod: "GET" requestSize: "395" requestUrl: "https://growthgeeks-q42lz4rc5a-uc.a.run.app/" responseSize: "870" serverIp: "216.239.32.53" status: 404 userAgent: "Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.22621.963" } insertId: "647383350005b235faf2d636" labels: { instanceId: "004d9db0be8fbe61fa21785209ea77b301b910f3d3a85b98070364c3b7f349c0afa3801798354327d2c09ecf8a343e703ad66f1343b77e2e753b9b65110486dc4a" } logName: "projects/roas-164016/logs/run.googleapis.com%2Frequests" receiveTimestamp: "2023-05-28T16:37:09.377173714Z" resource: { labels: { project_id: "roas-164016" revision_name: "growthgeeks-00007-sqg" location: "us-central1" configuration_name: "growthgeeks" service_name: "growthgeeks" } type: "cloud_run_revision" } severity: "WARNING" spanId: "8423610564014712292" timestamp: "2023-05-28T16:37:09.368517Z" trace: "projects/roas-164016/traces/8a57dc8aba186cf525e63daa0fc2b6a1" traceSampled: true }
检查Gunicorn监听配置
当前Dockerfile使用config.gunicorn配置文件启动Gunicorn,务必确认该配置里的bind参数设置为0.0.0.0:8000。Cloud Run要求服务必须监听0.0.0.0而非localhost,否则外部请求无法到达应用。如果配置文件里没指定bind,直接修改Dockerfile的CMD命令,显式绑定地址:CMD gunicorn -b 0.0.0.0:8000 -c "python:config.gunicorn" "snakeeyes.app:create_app()"验证应用路由配置
本地正常但部署后404,大概率是生产环境下的路由问题。检查snakeeyes.app:create_app()中是否正确注册了根路径/的视图函数,确认没有环境变量导致路由前缀变更,或者生产环境下未加载必要的路由模块。本地镜像独立测试
不要依赖docker-compose的本地卷挂载,直接构建镜像并运行,模拟Cloud Run的运行环境:docker build -t snakeeyes . docker run -p 8000:8000 --env-file .env snakeeyes curl http://localhost:8000/如果此时也返回404,说明镜像构建有问题——比如代码未完整复制、依赖安装不彻底,或者启动命令缺失必要参数。
同步Cloud Run环境变量
部署时Cloud Run不会自动加载.env文件,需要手动在Cloud Run服务配置中添加所有.env里的环境变量。如果应用依赖某些变量初始化路由或数据库连接,缺失这些变量会导致服务无法正常响应请求。开启应用日志排查
修改Gunicorn启动命令,添加日志输出参数,让应用日志输出到stdout/stderr,这样Cloud Run就能捕获到详细的请求和错误信息:CMD gunicorn -b 0.0.0.0:8000 -c "python:config.gunicorn" --access-logfile - --error-logfile - "snakeeyes.app:create_app()"查看Cloud Run的应用日志,确认请求是否到达Gunicorn,以及应用内部是否有报错。
内容的提问来源于stack exchange,提问作者Filipe Ferminiano

