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

Docker容器中Uvicorn进程已运行但未监听8001端口求助

问题:Uvicorn进程已启动但未监听指定端口

现象详情

1. 容器内进程状态

root@chat-server-service-594dc96485-rpphl:~/chat-server# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  97084 17560 ?        Ssl  17:19   0:01 python3 -m uvicorn main:app --port 8001 --host 0.0.0.0 --reload
root         8  0.0  0.0  12224  5920 ?        S    17:19   0:00 /usr/local/bin/python3 -c from multiprocessing.resource_tracker import main;main(4)
root         9  0.0  0.0      0     0 ?        Z    17:19   0:01 [python3] <defunct>
root        14  0.0  0.0   4292  1504 pts/0    Ss   17:47   0:00 bash
root        65  0.0  0.0   6752  1536 pts/0    R+   17:54   0:00 ps aux

可见PID为1的进程是Uvicorn启动命令,但存在僵尸进程[python3] <defunct>。

2. 端口连接测试失败

root@chat-server-service-594dc96485-rpphl:~/chat-server# curl http://0.0.0.0:8001
curl: (7) Failed to connect to 0.0.0.0 port 8001: Connection refused

3. 手动执行命令正常运行

root@chat-server-service-594dc96485-rpphl:~/chat-server# python3 -m uvicorn main:app --port 8001 --host 0.0.0.0 --reload
INFO:     Will watch for changes in these directories: ['/root/chat-server']
INFO:     Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)
INFO:     Started reloader process [58] using WatchFiles
^CINFO:     Stopping reloader process [58]

4. 端口监听检查

root@chat-server-service-6f59d77848-wcj6c:~/chat-server# ps aux|grep python
root         1  0.1  0.2  97084 17784 ?        Ssl  17:27   0:00 python3 -m uvicorn main:app --port 8001 --host 0.0.0.0 --reload
root         7  0.0  0.0  12224  6852 ?        S    17:27   0:00 /usr/local/bin/python3 -c from multiprocessing.resource_tracker import main;main(4)
root         8  0.9  0.0      0     0 ?        Z    17:27   0:02 [python3] <defunct>
root        27  0.0  0.0   3236   720 pts/0    S+   17:31   0:00 grep python
root@chat-server-service-6f59d77848-wcj6c:~/chat-server# lsof -i:8001
# 无输出,说明无进程监听8001端口

当前使用的Dockerfile

FROM python:3.8

LABEL example (example@gmail.com)

ENV LANG=en_US.UTF-8 \
    LC_ALL=en_US.UTF-8 \
    TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
    && echo $TZ > /etc/timezone \
    && mkdir -p /root/chat-server 

ADD . /root/chat-server/

EXPOSE 8001

RUN pip3 install -r /root/chat-server/requirements.txt

WORKDIR /root/chat-server/
ENTRYPOINT exec python3 -m uvicorn main:app --port 8001 --host 0.0.0.0 --reload

解决方法

核心原因

Uvicorn的--reload模式会启动两个进程:负责监听文件变化的reloader主进程,以及实际处理请求的worker子进程。当该命令作为Docker容器的PID1进程运行时,子进程退出后会变成僵尸进程,且reloader无法正确重启worker,导致无进程监听端口。而手动执行命令时,进程不是PID1,信号处理和进程管理逻辑正常,因此能正常运行。

方案1:生产环境禁用热重载(推荐)

直接移除--reload参数,这是生产环境的标准做法,可避免不必要的进程开销和稳定性问题。修改Dockerfile的ENTRYPOINT:

WORKDIR /root/chat-server/
ENTRYPOINT exec python3 -m uvicorn main:app --port 8001 --host 0.0.0.0

重新构建镜像后运行,即可正常监听8001端口。

方案2:开发环境需热重载的处理方式

如果开发环境必须使用热重载,可通过以下方式修复:

  1. 使用tini管理进程:
    在Dockerfile中安装tini,让它作为PID1进程管理Uvicorn,确保信号正确传递给子进程:
    FROM python:3.8
    
    LABEL example (example@gmail.com)
    
    ENV LANG=en_US.UTF-8 \
        LC_ALL=en_US.UTF-8 \
        TZ=Asia/Shanghai
    
    # 安装tini
    RUN apt-get update && apt-get install -y --no-install-recommends tini \
        && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
        && echo $TZ > /etc/timezone \
        && mkdir -p /root/chat-server 
    
    ADD . /root/chat-server/
    
    EXPOSE 8001
    
    RUN pip3 install -r /root/chat-server/requirements.txt
    
    WORKDIR /root/chat-server/
    # 用tini启动命令
    ENTRYPOINT ["tini", "--", "python3", "-m", "uvicorn", "main:app", "--port", "8001", "--host", "0.0.0.0", "--reload"]
    
  2. 手动执行启动命令:
    不将带--reload的命令写入Dockerfile的ENTRYPOINT,而是启动容器后进入终端手动执行,或通过docker exec运行,此时进程不是PID1,可正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:47:48