Docker镜像本地docker-compose正常,部署至ECS/Heroku失败求助
Django Docker部署问题排查(AWS ECR + Heroku)
问题概述
本地通过docker-compose up可正常运行带Postgres数据库的Django电商项目,但部署时遇到两类问题:
- AWS ECR部署:镜像上传至ECR并启动ECS集群后,任务先处于PENDING状态,刷新后消失,CloudWatch无日志输出。
- 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附加组件:
- 在Heroku控制台为应用添加Postgres附加组件
- 修改Django
settings.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)解决步骤
- 验证镜像可用性:本地单独运行镜像,确认能正常启动:
docker run -p 8000:8000 app:django
- 数据库配置调整:AWS建议使用RDS作为Postgres数据库,修改Django
settings.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任务定义中添加上述环境变量。
- ECS任务配置检查:
- 确保任务定义中指定正确启动命令:
python3 manage.py runserver 0.0.0.0:8000 - 分配足够CPU/内存(至少256CPU、512内存)
- 安全组开放入站8000端口(或负载均衡器端口),以及出站连接RDS的5432端口
- 配置日志驱动为
awslogs,确保启动错误能被CloudWatch捕获
内容的提问来源于stack exchange,提问作者HK215
相关产品推荐
相关产品推荐

