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

FastAPI进程终止后Docker容器未自动重启求助

解决Docker中FastAPI进程终止后容器不自动重启的问题

问题原因

你通过os.kill(os.getpid(), signal.SIGTERM)终止FastAPI进程时,这会触发uvicorn的正常退出流程,进程最终以状态码0结束。而Docker的restart: always策略仅在进程**异常退出(状态码非0)**或被强制杀死时才会触发容器重启,因此当前配置无法触发重启。

另外,如果你的Dockerfile启动命令使用shell模式(比如CMD uvicorn main:app ...),容器的主进程会是Shell而非uvicorn。此时杀死uvicorn的PID后,Shell进程仍会存活,容器根本不会退出,自然不会触发重启。

解决方案

1. 让进程以非0状态码退出

替换os.kill为sys.exit(1),或者在发送SIGTERM后主动以非0码退出,确保Docker检测到异常:

import sys
# ...其他导入代码...

@app.on_event("startup")
async def startup_event() -> None:
    logging.info("VP: Starting Server")
    task = asyncio.create_task(task_func())
    try:
        await task
    except Exception as error:
        logging.error(f"Following exception has occured: {error}")
        logging.info("Exception has occured. Shutting down uvicorn server")
        # 触发shutdown事件后,以非0状态码退出
        os.kill(os.getpid(), signal.SIGTERM)
        await asyncio.sleep(1)  # 留时间执行清理操作
        sys.exit(1)

如果不需要执行shutdown事件,也可以直接发送SIGKILL强制杀死进程(但会跳过清理流程):

os.kill(os.getpid(), signal.SIGKILL)

2. 确保Docker容器主进程是uvicorn

修改Dockerfile的启动命令为exec形式,让uvicorn成为容器的PID 1进程:

# 正确写法:exec形式,uvicorn作为主进程
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

# 错误写法:shell模式,主进程是Shell
# CMD uvicorn main:app --host 0.0.0.0 --port 8000

3. 验证配置效果

  • 查看容器日志:docker logs events_consumer,确认异常信息和退出日志是否正常输出。
  • 检查退出状态码:docker inspect events_consumer --format='{{.State.ExitCode}}',如果输出为1,说明进程异常退出,Docker会触发重启。

内容的提问来源于stack exchange,提问作者Vedant Parikh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 03:57:54