首页 > 解决方案 > 在 Docker 中运行的 Python 版本错误

问题描述

无论我尝试什么,我的 Docker 容器都使用Python 3.10而不是我需要和指定的,即Python 3.7。如何强制 Docker 将 3.7 用于特定的图像/容器?

我是新手 Docker 用户,其中一些 Docker 配置文件不是我编写的,请原谅我的无知。

错误

这是错误。您可以清楚地看到 Docker 使用的是 Python 3.10。

website_1  | Traceback (most recent call last):
website_1  |   File "/code/manage.py", line 10, in <module>
website_1  |     execute_from_command_line(sys.argv)
website_1  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
website_1  |     utility.execute()
website_1  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 357, in execute
website_1  |     django.setup()
website_1  |   File "/usr/local/lib/python3.10/site-packages/django/__init__.py", line 24, in setup
website_1  |     apps.populate(settings.INSTALLED_APPS)
website_1  |   File "/usr/local/lib/python3.10/site-packages/django/apps/registry.py", line 120, in populate
website_1  |     app_config.ready()
website_1  |   File "/code/website/apps.py", line 11, in ready
website_1  |     import website.signals
website_1  |   File "/code/website/signals.py", line 4, in <module>
website_1  |     from wand.image import Image, Color
website_1  |   File "/usr/local/lib/python3.10/site-packages/wand/image.py", line 3383, in <module>
website_1  |     class Iterator(Resource, collections.Iterator):
website_1  | AttributeError: module 'collections' has no attribute 'Iterator'

Docker 配置文件

我的 Dockerfile

FROM python:3.7

# Setup some other prereqs needed:
RUN apt-get update && apt-get --assume-yes install imagemagick ghostscript sqlite3

# Set the stdout/stderr streams in Python to be unbuffered
ENV PYTHONUNBUFFERED 1

# Create a system user which we'll use later.
# We're using the 'apache' user since that's what we're trying to map
# outside the container -- it could be called anything, but apache is convenient
RUN useradd -u 48 apache
RUN groupmod -g 48 apache

# The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. 
# The resulting committed image will be used for the next step in the Dockerfile.
RUN mkdir /code

# The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions 
# that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used 
# in any subsequent Dockerfile instruction. 
WORKDIR /code

# COPY and RUN the requirements.txt into the docker container
COPY requirements.txt /code/
RUN pip3.7 install -r requirements.txt

# Our local user needs write access to a website and static files
RUN chown -R apache /code/

COPY . /code/

#Run the process as our local user:
USER apache

COPY docker-entrypoint.sh docker-entrypoint.sh
CMD ["/code/docker-entrypoint.sh"] 

docker-compose.yml:_

version: '3'

services:
  db:
     image: 'postgres'
     restart: always
     ports:
       - '1456'
     environment:
      - POSTGRES_DB=databasename
      - POSTGRES_USER=username
      - POSTGRES_PASSWORD=passwordname
     volumes:
      - postgres-data:/var/lib/postgresql/data
  website:    
    build:
      context: .
      dockerfile: Dockerfile
    restart: always
    command: python3 manage.py runserver 0.0.0.0:8000
    ports:
      - '127.0.0.1:8985:8000'
    volumes:
      - .:/code
    depends_on:
      - db
    command: ["./docker-entrypoint.sh", "db", "python", "manage.py"]
    links:
      - "db:database"
volumes:
    postgres-data:   

docker-entrypoint.sh

#!/bin/bash

# Collect static files
echo "Collecting static files"
python manage.py collectstatic --noinput

# Apply database migrations
echo "Running makemigrations and migrate"
python manage.py makemigrations
python manage.py migrate

echo "Running makemigrations and migrate explicitly to website (often fixes some first-time run issues)"
python manage.py makemigrations website
python manage.py migrate website

# Start server
echo "Starting server"
python manage.py runserver 0.0.0.0:8000

作为更新,我能够通过完全擦除图像、容器、重新启动计算机、Docker 等并重建来“修复”这个问题。

此外,如果它对其他人有用,对我有用的一项直觉检查是在交互式 shell 中运行图像并检查它使用的是哪个 Python 版本。

$ docker run --rm -it makelab_image sh
$ which python
/usr/local/bin/python
$ python --version
Python 3.7.12

标签: pythonpython-3.xdjangodockerdocker-compose

解决方案


除非你明确地Dockerfile升级 python,否则python versionin 图像是3.7毫无疑问的,至少在Dockerfile你买得起的时候我没有看到这个:

$ docker run --rm -it python:3.7 python --version
Python 3.7.12

另外,一个可能的原因可能是您过去有时为python:3.7with制作了错误的标签python:3.10,例如 next,那么它可能会导致您的问题:

$ docker tag python:3.10 python:3.7
$ docker run --rm -it python:3.7 python --version
Python 3.10.0

如果以上是您的情况,请执行下一步清理环境,然后重复您的步骤再次检查:

$ docker rmi python:3.7

推荐阅读