You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloud Run容器内Flask与Chainlit多端口部署故障求助

问题排查与解决方案

核心问题分析

1. Cloud Run单端口限制

Cloud Run每个服务仅允许对外暴露一个端口(默认8080),即使Dockerfile中EXPOSE了8080和8000,Cloud Run也只会映射你配置的单个端口,8000端口无法从外部网络访问,这是聊天功能无法使用的根本原因之一。

2. Flask重定向目标错误

app.py中redirect("http://localhost:8000")的逻辑存在问题:

  • 本地测试时,localhost指向你的本地机器,容器内的8000端口可以被本地浏览器访问;
  • 部署到Cloud Run后,用户浏览器的localhost是用户自己的设备,而非Cloud Run容器内部,因此会出现无法访问的错误。

3. 启动脚本的潜在问题

  • 依赖固定sleep时间等待Ollama启动,若Ollama启动较慢,会导致Chainlit因依赖未就绪而启动失败;
  • 后台进程的日志可能未被正确输出到stdout,导致Cloud Run日志中看不到Chainlit的运行记录。

分步解决方案

方案1:通过Flask反向代理整合服务(推荐)

将Chainlit服务通过Flask代理到同一个端口,避免多端口暴露问题,修改app.py如下:

from flask import Flask, redirect, render_template, request, Response
import requests

app = Flask(__name__)
# 容器内Chainlit服务的地址
CHAINLIT_SERVICE = "http://localhost:8000"

@app.route("/")
def home():
    return render_template("index.html")

@app.route("/chat")
def chat():
    # 重定向到代理后的Chainlit入口
    return redirect(f"{CHAINLIT_SERVICE}/chat")

# 代理所有Chainlit相关请求
@app.route("/<path:path>", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"])
def proxy_chainlit(path):
    target_url = f"{CHAINLIT_SERVICE}/{path}"
    # 转发请求到Chainlit
    req = requests.request(
        method=request.method,
        url=target_url,
        headers={k: v for k, v in request.headers.items() if k != "Host"},
        data=request.get_data(),
        cookies=request.cookies,
        allow_redirects=False
    )
    # 处理响应头,移除Cloud Run不兼容的字段
    excluded_headers = ["content-encoding", "content-length", "transfer-encoding", "connection"]
    response_headers = [
        (name, value) for name, value in req.raw.headers.items()
        if name.lower() not in excluded_headers
    ]
    return Response(req.content, req.status_code, response_headers)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

方案2:修复启动脚本,确保服务稳定启动

修改启动脚本,替换固定sleep为主动检查Ollama就绪状态,同时显式指定Chainlit的监听地址和端口,确保日志输出:

#!/bin/bash

# 启动Ollama后台服务
ollama serve &
OLLAMA_PID=$!

# 主动等待Ollama就绪(轮询API直到响应正常)
echo "🔵 Waiting for Ollama to initialize..."
until curl -s http://localhost:11434/api/tags > /dev/null; do
    sleep 1
done
echo "🟢 Ollama is ready!"

# 拉取所需Ollama模型(根据你的需求替换模型名)
ollama pull llama2

# 启动Chainlit,显式指定监听0.0.0.0和端口8000
echo "🔵 Starting Chainlit service..."
poetry run chainlit run --headless --host 0.0.0.0 --port 8000 src/chatbot.py &
CHAINLIT_PID=$!

# 启动Flask服务
echo "🔵 Starting Flask service..."
poetry run gunicorn -b 0.0.0.0:8080 src.app.app:app &
FLASK_PID=$!

# 等待任一进程退出,然后终止所有服务(保证容器优雅退出)
wait -n $OLLAMA_PID $CHAINLIT_PID $FLASK_PID
kill $OLLAMA_PID $CHAINLIT_PID $FLASK_PID 2>/dev/null

方案3:Cloud Run配置调整

  • 在Cloud Run服务配置中,确保容器端口设置为8080(与Flask监听端口一致);
  • 不需要配置8000端口,所有请求将通过Flask代理到容器内的Chainlit服务。

验证步骤

  1. 重新构建Docker镜像并推送到Cloud Run;
  2. 访问Cloud Run生成的域名首页,点击"chat"按钮;
  3. 查看Cloud Run日志,确认Ollama、Chainlit、Flask三个服务都正常启动;
  4. 测试聊天功能,确认可以正常与AI机器人交互。

内容的提问来源于stack exchange,提问作者Boubacar Traoré

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:23:18