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

Docker镜像本地docker-compose正常,部署至ECS/Heroku失败求助

Django Docker部署问题排查(AWS ECR + Heroku)

问题概述

本地通过docker-compose up可正常运行带Postgres数据库的Django电商项目,但部署时遇到两类问题:

  1. AWS ECR部署:镜像上传至ECR并启动ECS集群后,任务先处于PENDING状态,刷新后消失,CloudWatch无日志输出。
  2. Heroku部署:进程启动后立即退出,日志显示H14错误(无Web进程运行),执行python3命令后进程以状态码0退出。

Heroku错误日志

2022-11-25T05:13:31.719689+00:00 heroku[router]: at=error code=H14 desc="No web processes running" method=GET path="/" host=hk-comic-app.herokuapp.com request_id=ea683b1d-e869-4ea9-98aa-2b9ed08f7219 fwd="98.116.68.242" dyno= connect= service= status=503 bytes= protocol=https
2022-11-25T05:22:36.083750+00:00 app[api]: Scaled to app@1:Free by user 
2022-11-25T05:22:39.300239+00:00 heroku[app.1]: Starting process with command `python3`
2022-11-25T05:22:39.895200+00:00 heroku[app.1]: State changed from starting to up
2022-11-25T05:22:40.178736+00:00 heroku[app.1]: Process exited with status 0
2022-11-25T05:22:40.228638+00:00 heroku[app.1]: State changed from up to crashed
2022-11-25T05:22:40.232742+00:00 heroku[app.1]: State changed from crashed to starting
2022-11-25T05:22:43.937389+00:00 heroku[app.1]: Starting process with command `python3`
2022-11-25T05:22:44.610097+00:00 heroku[app.1]: State changed from starting to up
2022-11-25T05:22:45.130636+00:00 heroku[app.1]: Process exited with status 0
2022-11-25T05:22:45.180808+00:00 heroku[app.1]: State changed from up to crashed
2022-11-25T05:23:09.462805+00:00 heroku[router]: at=error code=H14 desc="No web processes running" method=GET path="/" host=hk-comic-app.herokuapp.com request_id=f4cc3e04-0257-4336-94b3-7e48094cabd4 fwd="98.116.68.242" dyno= connect= service= status=503 bytes= protocol=https

当前配置文件

Dockerfile

FROM python:3.9-slim-buster
ENV PYTHONUNBUFFERED=1
WORKDIR /django
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

docker-compose.yml

version: "3"
services:
  app:
    build: .
    volumes:
      - .:/django
      - ./wait-for-it.sh:/wait-for-it.sh
    ports:
      - 8000:8000
    image: app:django
    container_name: django_container
    command: /wait-for-it.sh db:5432 -- python3 manage.py runserver 0.0.0.0:8000
    depends_on:
      - db
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=comic_db
      - POSTGRES_USER=comic_user
      - POSTGRES_PASSWORD=password
    container_name: postgres_db

问题分析与解决方案

1. Dockerfile核心缺陷

当前Dockerfile仅安装依赖,未将项目代码复制到镜像内,也未定义默认启动命令。本地运行正常是依赖volumes: .:/django挂载本地代码,但部署到AWS/Heroku时,镜像本身无代码,导致容器启动后无有效进程可执行。

修改后的Dockerfile:

FROM python:3.9-slim-buster
ENV PYTHONUNBUFFERED=1
WORKDIR /django

# 复制项目代码(需提前创建.dockerignore排除不必要文件)
COPY . .

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

# 设置默认启动命令,可被外部配置覆盖
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]

2. Heroku部署修复

(1)启动命令错误

日志显示Heroku执行python3仅启动Python交互环境,未运行Django服务,导致进程立即退出。

解决:在项目根目录创建Procfile,指定Web进程启动命令:

web: python manage.py runserver 0.0.0.0:$PORT

Heroku自动分配端口,必须使用$PORT环境变量,不能硬编码8000。

(2)数据库配置适配

Heroku不支持通过docker-compose启动Postgres容器,需使用Heroku Postgres附加组件:

  1. 在Heroku控制台为应用添加Postgres附加组件
  2. 修改Djangosettings.py,读取Heroku提供的DATABASE_URL环境变量:
import os
import dj_database_url

# 本地开发数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'comic_db',
        'USER': 'comic_user',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': 5432,
    }
}

# 部署到Heroku时覆盖配置
if os.environ.get('DATABASE_URL'):
    DATABASES['default'] = dj_database_url.config(conn_max_age=600, ssl_require=True)

确保dj-database-url已添加到requirements.txt。

(3)Docker部署Heroku注意事项

  • 使用heroku container:push web和heroku container:release web推送镜像
  • 无需在Dockerfile硬编码端口,Heroku会自动映射

3. AWS ECR/ECS部署修复

(1)任务消失常见原因

  • 镜像本身无法启动(缺少代码、依赖缺失)
  • ECS实例资源不足(CPU/内存不够)
  • 网络配置错误(安全组未开放端口、无法连接数据库)

(2)解决步骤

  1. 验证镜像可用性:本地单独运行镜像,确认能正常启动:
docker run -p 8000:8000 app:django
  1. 数据库配置调整:AWS建议使用RDS作为Postgres数据库,修改Djangosettings.py通过环境变量读取RDS信息:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DB_NAME'),
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
        'HOST': os.environ.get('DB_HOST'),
        'PORT': os.environ.get('DB_PORT', 5432),
    }
}

在ECS任务定义中添加上述环境变量。

  1. ECS任务配置检查:
  • 确保任务定义中指定正确启动命令:python3 manage.py runserver 0.0.0.0:8000
  • 分配足够CPU/内存(至少256CPU、512内存)
  • 安全组开放入站8000端口(或负载均衡器端口),以及出站连接RDS的5432端口
  • 配置日志驱动为awslogs,确保启动错误能被CloudWatch捕获

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:05:28