
Bild vom Autor
# Einführung
Python und Datenprojekte haben ein Abhängigkeitsproblem. Zwischen Python-Versionen, virtuellen Umgebungen, Paketen auf Systemebene und Betriebssystemunterschieden kann es manchmal länger dauern, den Code einer anderen Individual auf Ihrem Pc zum Laufen zu bringen, als den Code selbst zu verstehen.
Docker löst dieses Drawback, indem Sie Ihren Code und seine gesamte Umgebung – Python-Model, Abhängigkeiten, Systembibliotheken – in einem einzigen Artefakt namens Picture packen. Von dem Picture aus können Sie Container starten, die auf Ihrem Laptop computer, dem Pc Ihres Teamkollegen und einem Cloud-Server identisch laufen. Sie beenden das Debuggen von Umgebungen und beginnen mit der Auslieferung der Arbeit.
In diesem Artikel lernen Sie Docker anhand praktischer Beispiele kennen, wobei der Schwerpunkt auf Datenprojekten liegt: Containerisierung eines Skripts, Bereitstellung eines Modells für maschinelles Lernen FastAPIVerkabelung einer Multi-Service-Pipeline mit Docker Composeund Planen eines Jobs mit einem Cron-Container.
# Voraussetzungen
Bevor Sie die Beispiele durcharbeiten, benötigen Sie:
- Docker und Docker Compose für Ihr Betriebssystem installiert. Folgen Sie dem Offizielle Installationsanleitung für Ihre Plattform.
- Vertrautheit mit der Befehlszeile und Python.
- Vertrautheit mit dem Schreiben einer Docker-Datei, dem Erstellen eines Photographs und dem Ausführen eines Containers aus diesem Picture.
Wenn Sie eine kurze Auffrischung wünschen, finden Sie hier einige Artikel, die Sie auf den neuesten Stand bringen:
Sie benötigen keine umfassenden Docker-Kenntnisse, um mitzumachen. Jedes Beispiel erklärt, was im Laufe der Zeit passiert.
# Containerisieren eines Python-Skripts mit angehefteten Abhängigkeiten
Beginnen wir mit dem häufigsten Anwendungsfall: Sie haben ein Python-Skript und ein necessities.txtund Sie möchten, dass es überall zuverlässig läuft.
Wir erstellen ein Datenbereinigungsskript, das eine CSV-Rohdatei für Verkäufe liest, Duplikate entfernt, fehlende Werte ergänzt und eine bereinigte Model auf die Festplatte schreibt.
// Strukturierung des Projekts
Das Projekt ist wie folgt organisiert:
data-cleaner/
├── Dockerfile
├── necessities.txt
├── clean_data.py
└── information/
└── raw_sales.csv
// Das Drehbuch schreiben
Hier ist das Datenbereinigungsskript, das verwendet wird Pandas um die schwere Arbeit zu erledigen:
# clean_data.py
import pandas as pd
import os
INPUT_PATH = "information/raw_sales.csv"
OUTPUT_PATH = "information/cleaned_sales.csv"
print("Studying information...")
df = pd.read_csv(INPUT_PATH)
print(f"Rows earlier than cleansing: {len(df)}")
# Drop duplicate rows
df = df.drop_duplicates()
# Fill lacking numeric values with column median
for col in df.select_dtypes(embrace="quantity").columns:
df(col) = df(col).fillna(df(col).median())
# Fill lacking textual content values with 'Unknown'
for col in df.select_dtypes(embrace="object").columns:
df(col) = df(col).fillna('Unknown')
print(f"Rows after cleansing: {len(df)}")
df.to_csv(OUTPUT_PATH, index=False)
print(f"Cleaned file saved to {OUTPUT_PATH}")
// Abhängigkeiten anheften
Es ist wichtig, genaue Versionen anzuheften. Ohne es, pip set up pandas Möglicherweise werden unterschiedliche Versionen auf verschiedenen Computern installiert. Angepinnte Versionen garantieren, dass jeder das gleiche Verhalten erhält. Die genauen Versionen können Sie im festlegen necessities.txt Datei etwa so:
pandas==2.2.0
openpyxl==3.1.2
// Definieren der Docker-Datei
Diese Docker-Datei erstellt ein minimales, Cache-freundliches Picture für das Reinigungsskript:
# Use a slim Python 3.11 base picture
FROM python:3.11-slim
# Set the working listing contained in the container
WORKDIR /app
# Copy and set up dependencies first (for layer caching)
COPY necessities.txt .
RUN pip set up --no-cache-dir -r necessities.txt
# Copy the script into the container
COPY clean_data.py .
# Default command to run when the container begins
CMD ("python", "clean_data.py")
Hier gibt es einige Dinge, die es wert sind, erklärt zu werden. Wir verwenden python:3.11-slim anstelle des vollständigen Python-Photographs, da es wesentlich kleiner ist und nicht benötigte Pakete entfernt.
Wir kopieren necessities.txt bevor Sie den Relaxation des Codes kopieren. Dies ist beabsichtigt. Docker erstellt Bilder in Ebenen und speichert jedes einzelne im Cache. Wenn du dich nur änderst clean_data.pyDocker wird beim nächsten Construct nicht alle Ihre Abhängigkeiten neu installieren. Es verwendet die zwischengespeicherte Pip-Ebene wieder und springt direkt zum Kopieren Ihres aktualisierten Skripts. Mit dieser kleinen Bestellentscheidung können Sie Minuten beim Wiederaufbau einsparen.
// Bauen und Laufen
Nachdem das Picture erstellt wurde, können Sie den Container ausführen und Ihren lokalen Datenordner bereitstellen:
# Construct the picture and tag it
docker construct -t data-cleaner .
# Run it, mounting your native information/ folder into the container
docker run --rm -v $(pwd)/information:/app/information data-cleaner
Der -v $(pwd)/information:/app/information Flag mountet Ihr lokales information/ Ordner in den Container unter /app/information. Auf diese Weise liest das Skript Ihre CSV-Datei und die bereinigte Ausgabe wird auf Ihren Pc zurückgeschrieben. Es wird nichts in das Picture eingebrannt und die Daten verbleiben in Ihrem Dateisystem.
Der --rm Flag entfernt den Container automatisch, nachdem er fertig ist. Da es sich um ein einmaliges Skript handelt, gibt es keinen Grund, einen gestoppten Container herumliegen zu lassen.
# Bereitstellung eines Modells für maschinelles Lernen mit FastAPI
Sie haben ein Modell trainiert und möchten es über HTTP verfügbar machen, damit andere Dienste Daten senden und Vorhersagen zurückerhalten können. FastAPI funktioniert hierfür hervorragend: Es ist schnell, leichtgewichtig und übernimmt die Eingabevalidierung Pydantisch.
// Strukturierung des Projekts
Das Projekt trennt das Modellartefakt vom Anwendungscode:
ml-api/
├── Dockerfile
├── necessities.txt
├── app.py
└── mannequin.pkl
// Schreiben der App
Die folgende App lädt das Modell einmal beim Begin und stellt ein bereit /predict Endpunkt:
# app.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import pickle
import numpy as np
app = FastAPI(title="Gross sales Forecast API")
# Load the mannequin as soon as at startup
with open("mannequin.pkl", "rb") as f:
mannequin = pickle.load(f)
class PredictRequest(BaseModel):
area: str
month: int
marketing_spend: float
units_in_stock: int
class PredictResponse(BaseModel):
area: str
predicted_revenue: float
@app.get("/well being")
def well being():
return {"standing": "okay"}
@app.put up("/predict", response_model=PredictResponse)
def predict(request: PredictRequest):
attempt:
options = ((
request.month,
request.marketing_spend,
request.units_in_stock
))
prediction = mannequin.predict(options)
return PredictResponse(
area=request.area,
predicted_revenue=spherical(float(prediction(0)), 2)
)
besides Exception as e:
increase HTTPException(status_code=500, element=str(e))
Der PredictRequest Die Klasse führt die Eingabevalidierung für Sie durch. Wenn jemand eine Anfrage mit einem fehlenden Feld oder einer Zeichenfolge sendet, in der eine Zahl erwartet wird, lehnt FastAPI diese mit einer eindeutigen Fehlermeldung ab, bevor Ihr Modellcode überhaupt ausgeführt wird. Das Modell wird einmal beim Begin geladen – nicht bei jeder Anfrage – wodurch die Antwortzeiten kurz bleiben.
Der /well being endpoint ist eine kleine, aber wichtige Ergänzung: Docker, Load Balancer und Cloud-Plattformen prüfen damit, ob Ihr Dienst tatsächlich betriebsbereit ist.
// Definieren der Docker-Datei
Diese Docker-Datei backt das Modell direkt in das Picture, sodass der Container vollständig eigenständig ist:
FROM python:3.11-slim
WORKDIR /app
COPY necessities.txt .
RUN pip set up --no-cache-dir -r necessities.txt
# Copy the mannequin and the app collectively
COPY mannequin.pkl .
COPY app.py .
EXPOSE 8000
CMD ("uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000")
Der mannequin.pkl wird zum Zeitpunkt der Erstellung in das Bild integriert. Das bedeutet, dass der Container völlig eigenständig ist und Sie beim Ausführen nichts mounten müssen. Der --host 0.0.0.0 Flagge erzählt Uvicorn um alle Netzwerkschnittstellen im Container abzuhören, nicht nur localhost. Ohne dies können Sie die API nicht von außerhalb des Containers erreichen.
// Bauen und Laufen
Erstellen Sie das Picture und starten Sie den API-Server:
docker construct -t ml-api .
docker run --rm -p 8000:8000 ml-api
Testen Sie es mit Curl:
curl -X POST http://localhost:8000/predict
-H "Content material-Kind: software/json"
-d '{"area": "North", "month": 3, "marketing_spend": 5000.0, "units_in_stock": 320}'
# Erstellen einer Multi-Service-Pipeline mit Docker Compose
Echte Datenprojekte umfassen selten nur einen Prozess. Möglicherweise benötigen Sie eine Datenbank, ein Skript, das Daten hineinlädt, und ein Dashboard, das daraus liest – alles läuft zusammen.
Mit Docker Compose können Sie mehrere Container als eine einzige Anwendung definieren und ausführen. Jeder Dienst hat seinen eigenen Container, aber alle teilen sich ein privates Netzwerk, damit sie miteinander kommunizieren können.
// Strukturierung des Projekts
Die Pipeline teilt jeden Dienst in sein eigenes Unterverzeichnis auf:
pipeline/
├── docker-compose.yml
├── loader/
│ ├── Dockerfile
│ ├── necessities.txt
│ └── load_data.py
└── dashboard/
├── Dockerfile
├── necessities.txt
└── app.py
// Definieren der Compose-Datei
Diese Compose-Datei deklariert alle drei Dienste und verbindet sie mit Integritätsprüfungen und gemeinsam genutzten URL-Umgebungsvariablen:
# docker-compose.yml
model: "3.9"
companies:
db:
picture: postgres:15
surroundings:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
POSTGRES_DB: analytics
volumes:
- pgdata:/var/lib/postgresql/information
healthcheck:
check: ("CMD-SHELL", "pg_isready -U admin -d analytics")
interval: 5s
retries: 5
loader:
construct: ./loader
depends_on:
db:
situation: service_healthy
surroundings:
DATABASE_URL: postgresql://admin:secret@db:5432/analytics
dashboard:
construct: ./dashboard
depends_on:
db:
situation: service_healthy
ports:
- "8501:8501"
surroundings:
DATABASE_URL: postgresql://admin:secret@db:5432/analytics
volumes:
pgdata:
// Schreiben des Loader-Skripts
Dieses Skript wartet kurz auf die Datenbank und lädt dann mithilfe von eine CSV-Datei in die Verkaufstabelle SQLAlchemy:
# loader/load_data.py
import pandas as pd
from sqlalchemy import create_engine
import os
import time
DATABASE_URL = os.environ("DATABASE_URL")
# Give the DB a second to be totally prepared
time.sleep(3)
engine = create_engine(DATABASE_URL)
df = pd.read_csv("sales_data.csv")
df.to_sql("gross sales", engine, if_exists="substitute", index=False)
print(f"Loaded {len(df)} rows into the gross sales desk.")
Schauen wir uns die Compose-Datei genauer an. Jeder Dienst wird in einem eigenen Container ausgeführt, sie befinden sich jedoch alle im selben von Docker verwalteten Netzwerk, sodass sie einander über den Dienstnamen als Hostnamen erreichen können. Der Lader verbindet sich mit db:5432 – und nicht localhost – weil db ist der Dienstname und Docker übernimmt die DNS-Auflösung automatisch.
Der Gesundheitscheck am PostgreSQL Service ist wichtig. depends_on allein wartet nur darauf, dass der Container startet, nicht darauf, dass PostgreSQL bereit ist, Verbindungen anzunehmen. Der Gesundheitscheck verwendet pg_isready um zu bestätigen, dass die Datenbank tatsächlich aktiv ist, bevor der Loader versucht, eine Verbindung herzustellen. Der pgdata Das Quantity behält die Datenbank zwischen den Läufen bei. Durch das Stoppen und Neustarten der Pipeline werden Ihre Daten nicht gelöscht.
// Alles anfangen
Rufen Sie alle Dienste mit einem einzigen Befehl auf:
docker compose up --build
Um alles zu stoppen, führen Sie Folgendes aus:
# Jobs mit einem Cron-Container planen
Manchmal muss ein Skript nach einem Zeitplan ausgeführt werden. Möglicherweise ruft es stündlich Daten von einer API ab und schreibt sie in eine Datenbank oder eine Datei. Für etwas so Einfaches möchten Sie kein vollständiges Orchestrierungssystem wie Airflow einrichten. Ein Cron-Container erledigt die Arbeit sauber.
// Strukturierung des Projekts
Das Projekt enthält neben dem Skript und der Docker-Datei eine Crontab-Datei:
data-fetcher/
├── Dockerfile
├── necessities.txt
├── fetch_data.py
└── crontab
// Schreiben des Abrufskripts
Dieses Skript verwendet Anfragen um einen API-Endpunkt zu erreichen und die Ergebnisse als zeitgestempelte CSV-Datei zu speichern:
# fetch_data.py
import requests
import pandas as pd
from datetime import datetime
import os
API_URL = "https://api.instance.com/gross sales/newest"
OUTPUT_DIR = "/app/output"
os.makedirs(OUTPUT_DIR, exist_ok=True)
print(f"({datetime.now()}) Fetching information...")
response = requests.get(API_URL, timeout=10)
response.raise_for_status()
information = response.json()
df = pd.DataFrame(information("data"))
timestamp = datetime.now().strftime("%Ypercentmpercentd_percentHpercentM")
output_path = f"{OUTPUT_DIR}/sales_{timestamp}.csv"
df.to_csv(output_path, index=False)
print(f"({datetime.now()}) Saved {len(df)} data to {output_path}")
// Definieren der Crontab
Die Crontab plant die stündliche Ausführung des Skripts und leitet alle Ausgaben in eine Protokolldatei um:
# Run each hour, on the hour
0 * * * * python /app/fetch_data.py >> /var/log/fetch.log 2>&1
Der >> /var/log/fetch.log 2>&1 Der Teil leitet sowohl die Standardausgabe als auch die Fehlerausgabe in eine Protokolldatei um. So untersuchen Sie, was im Nachhinein passiert ist.
// Definieren der Docker-Datei
Diese Docker-Datei installiert cron, registriert den Zeitplan und sorgt dafür, dass er im Vordergrund läuft:
FROM python:3.11-slim
# Set up cron
RUN apt-get replace && apt-get set up -y cron && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY necessities.txt .
RUN pip set up --no-cache-dir -r necessities.txt
COPY fetch_data.py .
COPY crontab /and many others/cron.d/fetch-job
# Set appropriate permissions and register the crontab
RUN chmod 0644 /and many others/cron.d/fetch-job && crontab /and many others/cron.d/fetch-job
# cron -f runs cron within the foreground, which is required for Docker
CMD ("cron", "-f")
Der cron -f Flagge ist hier wichtig. Docker hält einen Container am Leben, solange sein Hauptprozess läuft. Wenn cron im Hintergrund ausgeführt würde (Standardeinstellung), würde der Hauptprozess sofort beendet und Docker würde den Container stoppen. Der -f Flag sorgt dafür, dass Cron im Vordergrund läuft, sodass der Container am Leben bleibt.
// Bauen und Laufen
Erstellen Sie das Picture und starten Sie den Container im getrennten Modus:
docker construct -t data-fetcher .
docker run -d --name fetcher -v $(pwd)/output:/app/output data-fetcher
Überprüfen Sie jederzeit die Protokolle:
docker exec fetcher cat /var/log/fetch.log
Der Ausgabeordner wird von Ihrem lokalen Pc bereitgestellt, sodass die CSV-Dateien in Ihrem Dateisystem landen, obwohl das Skript im Container ausgeführt wird.
# Zusammenfassung
Ich hoffe, Sie fanden diesen Docker-Artikel hilfreich. Docker muss nicht kompliziert sein. Beginnen Sie mit dem ersten Beispiel, tauschen Sie Ihr eigenes Skript und Ihre Abhängigkeiten ein und machen Sie sich mit dem Construct-Run-Zyklus vertraut. Sobald Sie das getan haben, folgen die anderen Muster ganz natürlich. Docker passt intestine, wenn:
- Sie benötigen reproduzierbare Umgebungen für alle Maschinen oder Teammitglieder
- Sie geben Skripte oder Modelle frei, für die bestimmte Abhängigkeitsanforderungen gelten
- Sie bauen Multi-Service-Systeme auf, die zuverlässig zusammenarbeiten müssen
- Sie möchten die Bereitstellung überall ohne Reibungsverluste durchführen
Allerdings müssen Sie nicht immer Docker für Ihre gesamte Python-Arbeit verwenden. Es ist wahrscheinlich übertrieben, wenn:
- Sie führen schnelle, explorative Analysen nur für sich selbst durch
- Ihr Skript weist über die Standardbibliothek hinaus keine externen Abhängigkeiten auf
- Sie stehen am Anfang eines Projekts und Ihre Anforderungen ändern sich schnell
Wenn Sie daran interessiert sind, noch weiter zu gehen, schauen Sie hier vorbei 5 einfache Schritte zur Beherrschung von Docker für Information Science.
Viel Spaß beim Codieren!
Bala Priya C ist ein Entwickler und technischer Redakteur aus Indien. Sie arbeitet gerne an der Schnittstelle von Mathematik, Programmierung, Datenwissenschaft und Inhaltserstellung. Zu ihren Interessen- und Fachgebieten gehören DevOps, Datenwissenschaft und Verarbeitung natürlicher Sprache. Sie liebt es zu lesen, zu schreiben, zu programmieren und Kaffee zu trinken! Derzeit arbeitet sie daran, zu lernen und ihr Wissen mit der Entwickler-Neighborhood zu teilen, indem sie Tutorials, Anleitungen, Meinungsbeiträge und mehr verfasst. Bala erstellt außerdem ansprechende Ressourcenübersichten und Programmier-Tutorials.
