Verstehen und Beheben der ModuleNotFoundError
Nachdem wir nun auf die ModuleNotFoundError gestoßen sind, wollen wir verstehen, warum sie aufgetreten ist und wie man sie behebt.
Warum tritt die ModuleNotFoundError in Docker auf?
Die ModuleNotFoundError tritt in Docker aus mehreren häufigen Gründen auf:
- Fehlende Abhängigkeitsinstallation: Wir haben die erforderlichen Python-Pakete nicht im Docker-Image installiert.
- Falsche PYTHONPATH: Der Python-Interpreter kann die Module nicht an den erwarteten Orten finden.
- Probleme mit der Dateistruktur: Die Struktur des Anwendungscodes stimmt nicht mit der Art und Weise überein, wie Importe durchgeführt werden.
In unserem Fall trat der Fehler auf, weil wir das requests-Paket nicht in unserem Docker-Image installiert haben. Im Gegensatz zu unserer lokalen Entwicklungsumgebung, in der wir dieses Paket möglicherweise global installiert haben, sind Docker-Container isolierte Umgebungen.
Methode 1: Installieren von Abhängigkeiten mit pip im Dockerfile
Ändern wir unser Dockerfile, um die erforderlichen Abhängigkeiten zu installieren:
nano Dockerfile
Aktualisieren Sie das Dockerfile mit dem folgenden Inhalt:
FROM python:3.9-slim
WORKDIR /app
COPY app.py .
## Fix Method 1: Directly install the required package
RUN pip install requests==2.28.1
CMD ["python", "app.py"]
Lassen Sie uns dieses aktualisierte Image erstellen und ausführen:
docker build -t python-app-fixed-1 .
Sie sollten eine Ausgabe sehen, die die Paketinstallation enthält:
Sending build context to Docker daemon 3.072kB
Step 1/5 : FROM python:3.9-slim
---> 3a4bac80b3ea
Step 2/5 : WORKDIR /app
---> Using cache
---> a8a4f574dbf5
Step 3/5 : COPY app.py .
---> Using cache
---> 7d5ae315f84b
Step 4/5 : RUN pip install requests==2.28.1
---> Running in 5a6d7e8f9b0c
Collecting requests==2.28.1
Downloading requests-2.28.1-py3-none-any.whl (62 kB)
Collecting charset-normalizer<3,>=2
Downloading charset_normalizer-2.1.1-py3-none-any.whl (39 kB)
Collecting certifi>=2017.4.17
Downloading certifi-2022.9.24-py3-none-any.whl (161 kB)
Collecting idna<4,>=2.5
Downloading idna-3.4-py3-none-any.whl (61 kB)
Collecting urllib3<1.27,>=1.21.1
Downloading urllib3-1.26.12-py2.py3-none-any.whl (140 kB)
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests
Successfully installed certifi-2022.9.24 charset-normalizer-2.1.1 idna-3.4 requests-2.28.1 urllib3-1.26.12
---> 2b3c4d5e6f7g
Removing intermediate container 5a6d7e8f9b0c
Step 5/5 : CMD ["python", "app.py"]
---> Running in 8h9i0j1k2l3m
---> 3n4o5p6q7r8s
Removing intermediate container 8h9i0j1k2l3m
Successfully built 3n4o5p6q7r8s
Successfully tagged python-app-fixed-1:latest
Nun lassen Sie uns den korrigierten Container ausführen:
docker run python-app-fixed-1
Sie sollten eine ähnliche Ausgabe wie diese sehen:
Status code: 200
Content length: 1256 characters
Großartig! Die Anwendung läuft jetzt erfolgreich, weil wir die erforderliche Abhängigkeit installiert haben.
Methode 2: Verwenden von requirements.txt für die Abhängigkeitsverwaltung
Obwohl die direkte Installation von Paketen funktioniert, ist es eine bessere Vorgehensweise, eine requirements.txt-Datei für eine organisiertere Abhängigkeitsverwaltung zu verwenden. Aktualisieren wir unser Dockerfile:
nano Dockerfile
Aktualisieren Sie das Dockerfile mit dem folgenden Inhalt:
FROM python:3.9-slim
WORKDIR /app
## Copy requirements first to leverage Docker cache
COPY requirements.txt .
## Fix Method 2: Use requirements.txt
RUN pip install -r requirements.txt
## Copy the rest of the application
COPY app.py .
CMD ["python", "app.py"]
Dieser Ansatz hat mehrere Vorteile:
- Er trennt die Abhängigkeitsverwaltung vom Code
- Er erleichtert die Aktualisierung von Abhängigkeiten
- Er folgt Best Practices für das Caching von Docker-Image-Layern
Lassen Sie uns dieses aktualisierte Image erstellen und ausführen:
docker build -t python-app-fixed-2 .
Sie sollten eine ähnliche Ausgabe wie beim vorherigen Build sehen, aber dieses Mal wird requirements.txt verwendet:
Sending build context to Docker daemon 4.096kB
Step 1/5 : FROM python:3.9-slim
---> 3a4bac80b3ea
Step 2/5 : WORKDIR /app
---> Using cache
---> a8a4f574dbf5
Step 3/5 : COPY requirements.txt .
---> Using cache
---> b2c3d4e5f6g7
Step 4/5 : RUN pip install -r requirements.txt
---> Running in h8i9j0k1l2m3
Collecting requests==2.28.1
Using cached requests-2.28.1-py3-none-any.whl (62 kB)
Collecting charset-normalizer<3,>=2
Using cached charset_normalizer-2.1.1-py3-none-any.whl (39 kB)
Collecting idna<4,>=2.5
Using cached idna-3.4-py3-none-any.whl (61 kB)
Collecting certifi>=2017.4.17
Using cached certifi-2022.9.24-py3-none-any.whl (161 kB)
Collecting urllib3<1.27,>=1.21.1
Using cached urllib3-1.26.12-py2.py3-none-any.whl (140 kB)
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests
Successfully installed certifi-2022.9.24 charset-normalizer-2.1.1 idna-3.4 requests-2.28.1 urllib3-1.26.12
---> n4o5p6q7r8s9
Removing intermediate container h8i9j0k1l2m3
Step 5/5 : COPY app.py .
---> t0u1v2w3x4y5
Step 6/6 : CMD ["python", "app.py"]
---> Running in z5a6b7c8d9e0
---> f1g2h3i4j5k6
Removing intermediate container z5a6b7c8d9e0
Successfully built f1g2h3i4j5k6
Successfully tagged python-app-fixed-2:latest
Nun lassen Sie uns den Container ausführen:
docker run python-app-fixed-2
Sie sollten die gleiche erfolgreiche Ausgabe sehen:
Status code: 200
Content length: 1256 characters
Sie haben die ModuleNotFoundError erfolgreich mit zwei verschiedenen Methoden behoben!