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
相关产品推荐
相关产品推荐

