Неправильная версия Python, запущенная в Docker

Как бы я ни пытался, мой контейнер 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'

Файлы конфигурации докера

Мой 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

Создайте runtime.txt в корневом каталоге и напишите в нем:

python-3.7

Если только вы явно в Dockerfile обновляете python, python version в изображении 3.7 несомненно, по крайней мере, в Dockerfile, который вы себе позволяете, я этого не видел:

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

Дополнительно, возможная причина, возможно, вы иногда в прошлом, делаете неправильный тег для python:3.7 с python:3.10, как следующий, тогда это может привести к вашим проблемам:

$ 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

У меня была такая же проблема, но с базовым образом nvidia (FROM nvidia/cuda:11.2.0-cudnn8-runtime-ubuntu20.04). Это сработало для меня, надеюсь, сработает и для вас. Добавьте это в Dockerfile:

RUN apt-get update && apt-get install -y \
    build-essential \
    zlib1g-dev \
    libncurses5-dev \
    libgdbm-dev \
    libnss3-dev \
    libssl-dev \
    libsqlite3-dev \
    libreadline-dev \
    libffi-dev \
    wget \
    libbz2-dev

RUN wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz && \
    tar -xf Python-3.7.4.tgz && \
    cd Python-3.7.4 && \
    ./configure --enable-optimizations && \
    make -j$(nproc) && \
    sudo make altinstall

после этого вы можете использовать python 3.7 с помощью команды python3.7 и устанавливать пакеты с помощью pip3.7 install [packag name].

Это ./configure --enable-optimizations установит python 3.7 из исходного кода с оптимизацией для ОС, и это займет много времени.

Вернуться на верх