Docker化Django应用AWS部署报错:pyenv: gunicorn: command not found
Django Docker化应用AWS部署时gunicorn找不到的问题诊断与解决
问题描述
Docker化的Django应用部署在AWS t3a.micro EC2实例上,更新Debian基础镜像和PostgreSQL相关配置后,启动时出现以下报错:
pyenv: gunicorn: command not found
此前版本可正常运行,本地通过docker-compose up启动容器并进入后,gunicorn命令能正常执行,且requirements.txt中已明确包含gunicorn依赖。
当前环境配置
Dockerfile
FROM andrejreznik/python-gdal:py3.11.10-gdal3.6.2 ENV PYTHONUNBUFFERED 1 RUN pip install --upgrade pip RUN apt-get update RUN apt-get upgrade -y RUN apt-get install postgresql-15 postgresql-server-dev-15 -y RUN mkdir /code WORKDIR /code COPY requirements.txt /code/ RUN pip install -r requirements.txt COPY . /code/ ARG ALLOWED_HOSTS ARG AWS_ACCESS_KEY_ID ARG AWS_S3_CUSTOM_DOMAIN ARG AWS_SECRET_ACCESS_KEY ARG AWS_STORAGE_BUCKET_NAME ARG AWS_SES_ACCESS_KEY_ID ARG AWS_SES_SECRET_ACCESS_KEY ARG CORS_ALLOWED_ORIGINS ARG DATABASE_HOST ARG DATABASE_NAME ARG DATABASE_PASSWORD ARG DATABASE_PORT ARG DATABASE_USER ARG SECRET_KEY ENV ALLOWED_HOSTS=${ALLOWED_HOSTS} ENV AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} ENV AWS_S3_CUSTOM_DOMAIN=${AWS_S3_CUSTOM_DOMAIN} ENV AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} ENV AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME} ENV AWS_SES_ACCESS_KEY_ID=${AWS_SES_ACCESS_KEY_ID} ENV AWS_SES_SECRET_ACCESS_KEY=${AWS_SES_SECRET_ACCESS_KEY} ENV CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS} ENV DATABASE_HOST=${DATABASE_HOST} ENV DATABASE_NAME=${DATABASE_NAME} ENV DATABASE_PASSWORD=${DATABASE_PASSWORD} ENV DATABASE_PORT=${DATABASE_PORT} ENV DATABASE_USER=${DATABASE_USER} ENV SECRET_KEY=${SECRET_KEY} EXPOSE 8000 RUN ["python", "manage.py", "collectstatic", "--noinput"] RUN ["python", "manage.py", "migrate"] CMD ["gunicorn", "--workers=4", "--bind=:8000", "my_app_backend.wsgi"]
requirements.txt
boto3==1.16.18 django==3.1 django-ckeditor==6.0.0 django-cors-headers==3.5.0 django-filter==2.4.0 django-import-export>=2.5.0 django-ses==1.0.3 django-simple-history==2.11.0 django-storages==1.10.1 djangorestframework==3.11.1 djangorestframework-gis==0.16 dj-database-url==0.5.0 gunicorn==20.0.4 Pillow==7.2.0 psycopg2-binary==2.9.10 mysql-connector-python>=8.0.21 timezonefinder>=4.2.0 pytz>=2020.1
本次修改内容
- Dockerfile:
- 基础镜像从
andrejreznik/python-gdal:stable更新为andrejreznik/python-gdal:py3.11.10-gdal3.6.2 - 添加
RUN apt-get install postgresql-15 postgresql-server-dev-15 -y指定PostgreSQL版本
- 基础镜像从
- requirements.txt:
- psycopg2依赖从
psycopg2==2.8.5更新为psycopg2-binary==2.9.10
- psycopg2依赖从
已做排查
在Dockerfile中添加命令验证gunicorn状态,结果显示:
#15 [11/17] RUN whereis gunicorn #15 sha256:b84e89b409fb5702af7f9ad1edce8817a23b733674211baae2edfd6e5baf1397 #15 0.213 gunicorn: /usr/local/pyenv/shims/gunicorn #15 DONE 0.2s #16 [12/17] RUN which gunicorn #16 sha256:0eb044442dfa9b6a75308ac8500fc2e75d4aa6685cfb7e044508a61d92d5b6dc #16 0.224 /usr/local/pyenv/shims/gunicorn #16 DONE 0.2s #17 [13/17] RUN dpkg --get-selections | grep '^g' #17 sha256:8a4451313e003399ca21a7e9a61c923e8573b869465e64a3dcd5ea581fbc019b #17 0.238 gcc install #17 0.238 gcc-12 install #17 0.238 gcc-12-base:amd64 install #17 0.238 git install #17 0.238 git-man install #17 0.238 gpgv install #17 0.238 grep install #17 0.238 gzip install #17 DONE 0.3s #18 [14/17] RUN pip list | grep 'gunicorn' #18 sha256:5391b3d15711450cd56c2e85ae4db5926644f6f616c5584570af60ae9cc4a1d9 #18 3.398 gunicorn 20.0.4 #18 DONE 3.4s
可见gunicorn已通过pip安装,且存在于/usr/local/pyenv/shims/gunicorn路径下。
解决建议
1. 使用gunicorn绝对路径执行
修改Dockerfile中的CMD命令,直接指定gunicorn的绝对路径,绕开环境变量PATH的问题:
CMD ["/usr/local/pyenv/shims/gunicorn", "--workers=4", "--bind=:8000", "my_app_backend.wsgi"]
2. 通过Python模块方式启动gunicorn
利用python -m的方式调用gunicorn,无需依赖系统PATH中的命令:
CMD ["python", "-m", "gunicorn", "--workers=4", "--bind=:8000", "my_app_backend.wsgi"]
3. 确保pyenv shims目录在PATH中
在Dockerfile中明确设置环境变量PATH,保证pyenv的shims目录被包含:
ENV PATH="/usr/local/pyenv/shims:/usr/local/pyenv/bin:$PATH"
将此命令添加到基础镜像之后,确保后续命令和启动时都能识别到pyenv管理的命令。
额外优化建议
避免在构建镜像时执行migrate和collectstatic,这类操作应该在容器启动时执行(比如通过启动脚本),因为构建时的数据库环境和运行时可能不一致,且镜像应该保持无状态。
内容的提问来源于stack exchange,提问作者skwidbreth
相关产品推荐
相关产品推荐

