无法访问GitHub Actions部署的FastAPI+Ngrok应用问题排查
我熟悉GitHub Actions用于CI/CD,但现在要部署一个基于模型的FastAPI应用——用Uvicorn提供服务,通过Ngrok暴露公网URL。日志显示所有服务正常运行,也给出了Ngrok公网地址,但就是无法通过该URL访问应用。
环境信息
- FastAPI应用:Uvicorn运行在
0.0.0.0:8000 - Ngrok:负责将应用暴露为公网URL
- GitHub Actions:统筹环境搭建、依赖安装及服务启动
GitHub Actions日志输出
Run uvicorn scripts.main:app --host 0.0.0.0 --port 8000 & INFO: Started server process [2832] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) FastAPI app running at https://c3f3-20-161-78-239.ngrok-free.app
当前状态
已允许8000端口的TCP流量,但https://c3f3-20-161-78-239.ngrok-free.app无法访问。
疑问
- GitHub Actions环境是否会影响Ngrok隧道的稳定性或可用性?
- 是否存在遗漏的常见配置陷阱导致无法访问Ngrok URL?
- 如何确保Ngrok隧道在GitHub Actions工作流运行期间保持活跃且可访问?
工作流文件
name: Deploy FastAPI Application on: push: branches: - main pull_request: branches: - main workflow_dispatch: jobs: train-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Train model run: python scripts/train_model.py env: PYTHONPATH: ${{ github.workspace }} - name: Public IP id: ip uses: haythem/public-ip@v1.3 - name: Print Public IP run: | echo "Public IPv4: ${{ steps.ip.outputs.ipv4 }}" echo "Public IPv6: ${{ steps.ip.outputs.ipv6 }}" - name: Install Ngrok run: | curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc > /dev/null echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list sudo apt update && sudo apt install ngrok - name: Allow port 8000 through UFW run: | sudo ufw allow 8000/tcp sudo ufw enable sudo ufw status - name: Start Ngrok run: | ngrok authtoken ${{ secrets.ngrok}} ngrok http 8000 & sleep 10 # Wait for ngrok to initialize NGROK_URL=$(curl --silent http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url') echo "NGROK_URL=${NGROK_URL}" >> $GITHUB_ENV - name: Deploy FastAPI application run: | uvicorn scripts.main:app --host 0.0.0.0 --port 8000 & sleep 10 # Allow server to start echo "FastAPI app running at ${{ env.NGROK_URL }}" - name: Debug Running Services run: | echo "Running processes:" ps aux echo "Docker containers:" docker ps echo "Listening ports:" sudo netstat -tulpn
1. GitHub Actions环境对Ngrok隧道的影响
GitHub Actions的运行器是临时虚拟机,工作流结束后会立即销毁。核心影响点:
- 运行器网络环境受限,部分地区可能无法访问Ngrok免费域名;
- GitHub Actions会自动清理步骤结束后的后台进程,用
&启动的服务可能在后续步骤执行后被终止; - 免费版Ngrok本身有并发连接限制,闲置隧道会自动关闭。
2. 常见配置陷阱排查
(1)服务启动顺序错误
当前先启动Ngrok再启动FastAPI,Ngrok初始化时会尝试连接本地8000端口,但此时后端服务未就绪,导致隧道未正确关联服务,转发失败。
(2)后台进程被强制终止
用&启动的Uvicorn/Ngrok属于后台进程,当前run步骤执行完成后,GitHub Actions会自动终止这些进程,后续即使有其他步骤,服务也可能已经停止。
(3)Ngrok认证或配置问题
- 检查
${{ secrets.ngrok}}是否配置正确,无效认证token会导致隧道无法正常转发; - 免费版Ngrok的隧道域名可能被部分地区网络屏蔽,可尝试更换隧道或使用自定义域名(需付费)。
(4)端口监听异常
查看Debug Running Services步骤的netstat输出,确认0.0.0.0:8000确实有uvicorn进程在监听,避免服务实际未启动或监听地址错误。
3. 确保隧道活跃可访问的方法
(1)调整服务启动顺序
先启动FastAPI,等待服务就绪后再启动Ngrok,确保隧道关联到正常运行的后端:
# 替换原有的Deploy和Start Ngrok步骤 - name: Start FastAPI application run: | uvicorn scripts.main:app --host 0.0.0.0 --port 8000 & # 用健康检查接口等待服务就绪,替代固定sleep until curl -s http://localhost:8000/health; do sleep 2; done - name: Start Ngrok run: | ngrok authtoken ${{ secrets.ngrok}} ngrok http 8000 & sleep 5 NGROK_URL=$(curl --silent http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url') echo "NGROK_URL=${NGROK_URL}" >> $GITHUB_ENV
注:需给FastAPI添加/health健康检查接口,确保服务真正启动完成。
(2)防止后台进程被终止
在工作流最后添加保持活跃的步骤,避免工作流提前结束导致服务终止:
- name: Keep workflow alive run: | while true; do sleep 30; done
GitHub Actions工作流最长运行时间为6小时,超时会自动终止。
(3)验证隧道状态
启动Ngrok后,调用其API确认隧道是否正确关联后端:
- name: Verify Ngrok tunnel run: | curl --silent http://localhost:4040/api/tunnels | jq '.tunnels[] | select(.public_url == "${{ env.NGROK_URL }}") | .config.addr'
确保返回结果为localhost:8000,说明隧道配置正常。
(4)查看Ngrok日志排查问题
添加步骤输出Ngrok日志,定位转发错误:
- name: Check Ngrok logs run: | ngrok http 8000 > ngrok.log 2>&1 & sleep 10 cat ngrok.log
日志中会显示认证失败、连接错误等关键信息。
内容的提问来源于stack exchange,提问作者Foxbat

