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

Docker容器部署FastAPI到Heroku启动失败求助

问题解决:Heroku部署Docker镜像启动失败(start.sh not found)

问题根源分析

从日志/bin/sh: 1: ./start.sh 53182: not found可以看出,shell将./start.sh 53182当成了单个命令名,而非./start.sh加参数53182;同时大概率存在脚本无执行权限、shebang缺失的问题。

解决方案步骤

1. 给start.sh添加可执行权限

Docker复制文件时会保留主机权限,若主机上脚本无执行权限,容器内也会继承该状态。在Dockerfile中添加权限设置:

WORKDIR /opt/app/server
COPY ./start.sh .
# 新增:赋予脚本执行权限
RUN chmod +x start.sh

2. 修正Dockerfile的CMD写法

当前CMD "./start.sh ${PORT}"的shell格式,在Heroku解析时容易出现参数合并问题,推荐两种更可靠的写法:

写法一:用exec格式CMD(通过shell解析环境变量)

exec格式不会自动替换环境变量,因此用shell包裹执行:

CMD ["/bin/sh", "-c", "./start.sh $PORT"]

写法二:让start.sh直接读取PORT环境变量(更简洁)

修改start.sh,不再传递端口参数,直接读取Heroku提供的环境变量:

#!/bin/sh
uvicorn api.app:app --host 0.0.0.0 --port $PORT

随后Dockerfile的CMD简化为:

CMD ["./start.sh"]

这种方式完全贴合Heroku的环境变量使用逻辑,避免参数传递问题。

3. 确保start.sh有正确的shebang

在start.sh的第一行必须添加shebang,指定执行脚本的shell:

#!/bin/sh
# 或#!/bin/bash,根据容器内预装的shell选择

缺失shebang会导致系统无法识别脚本的执行环境,进而触发"not found"错误。

4. 本地验证容器运行

修改完成后,本地重新构建镜像并运行,确认启动逻辑正常:

docker build -t my-fastapi-app .
docker run -p 8000:8000 -e PORT=8000 my-fastapi-app

可选:用Heroku.yml指定启动命令(若仍有问题)

如果以上调整后仍存在异常,可在项目根目录创建Heroku.yml,明确指定web进程的启动命令:

build:
  docker:
    web: Dockerfile
run:
  web: /bin/sh -c "./start.sh $PORT"

gonuit/heroku-docker-deploy会自动识别该文件并应用配置。

最终修改后的Dockerfile示例

FROM node:21 as ui-build

WORKDIR /opt/ui

COPY ui .
RUN npm ci && npm run build

FROM python:3.11 as final-build

WORKDIR /opt/app
COPY --from=ui-build /opt/ui/build ./ui/build
COPY server server

RUN cd server && pip install -r requirements.txt

EXPOSE $PORT

WORKDIR /opt/app/server
COPY ./start.sh .
RUN chmod +x start.sh

# 使用exec格式CMD,通过shell解析环境变量
CMD ["/bin/sh", "-c", "./start.sh $PORT"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:09:54