Heroku通过Docker部署Celery+Redis Python REST API配置与报错排查
Heroku部署Celery+Redis+Python REST API 配置指南
完全支持在Heroku平台通过Docker部署搭配Celery与Redis的Django/Flask/FastAPI REST API。
参考项目结构:
项目开源地址:fastapi_celery_redis
部署时Redis连接报错参考:
报错核心原因
- 自定义heroku.yml中Redis插件的
as: REDIS配置无效,Heroku Redis插件默认向所有进程注入的连接变量为REDIS_URL,代码侧若硬编码本地测试用的Redis地址(如redis://redis:6379/0)会直接连接失败 - Heroku的Docker容器部署不支持自定义桥接网络,web、worker进程无法通过容器名互相访问,所有服务连接必须读取平台注入的官方环境变量
- web进程未绑定Heroku动态分配的
$PORT端口,会导致外部流量无法接入服务
配置文件参考
本地开发使用docker-compose.yml
version: '3.8' services: web: build: ./app ports: - "8000:8000" volumes: - ./app:/app environment: - REDIS_URL=redis://redis:6379/0 - CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_RESULT_BACKEND=redis://redis:6379/0 depends_on: - redis - worker worker: build: ./worker_tasks volumes: - ./worker_tasks:/worker environment: - REDIS_URL=redis://redis:6379/0 - CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_RESULT_BACKEND=redis://redis:6379/0 depends_on: - redis redis: image: redis:7-alpine ports: - "6379:6379"
Web服务Dockerfile(存放于app目录,Django/Flask仅需替换对应启动命令)
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . # 本地开发默认使用8000端口,Heroku部署时自动读取平台分配的PORT变量 CMD uvicorn main:app --host 0.0.0.0 --port ${PORT:-8000}
Celery Worker服务Dockerfile(存放于worker_tasks目录)
FROM python:3.11-slim WORKDIR /worker COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . # 根据实际项目的Celery实例路径调整启动参数 CMD celery -A tasks worker --loglevel=info
修正后的heroku.yml
setup: addons: # 移除自定义as配置,使用平台默认注入的REDIS_URL变量 - plan: heroku-redis build: docker: web: app/Dockerfile worker: worker_tasks/Dockerfile run: web: uvicorn main:app --host 0.0.0.0 --port $PORT worker: celery -A tasks worker --loglevel=info
部署注意事项
- 所有Redis、Celery连接配置统一从环境变量读取,禁止硬编码本地服务地址
- 不要尝试在Heroku Docker部署中配置自定义内部网络、通过容器名访问跨进程服务,平台不提供该能力
- 确认requirements.txt包含所有运行依赖:对应Web框架(fastapi/flask/django)、ASGI/WSGI服务器(uvicorn/gunicorn)、celery、redis依赖包
- 若需要使用Celery Beat定时任务,可在heroku.yml的build、run段新增beat进程,复用worker镜像,启动命令替换为
celery -A tasks beat即可
内容的提问来源于stack exchange,提问作者Sebastian Jose
相关产品推荐
相关产品推荐

