Achter Fund (Uebung-Verweise) und Phase 8.3: Dockerfile
Zwei Dinge in einem Commit, weil beide den Plan abschliessen.
ACHTER FUND: sieben Saetze der Bauart "Uebung 8.5 laesst Sie diese Balance
untersuchen" - und sechs davon standen in alter Zaehlung. "8" war in Version
03 das QP/NLP-Kapitel, heute ist es Kapitel 11. Dieselbe Familie wie die
Denkfehler-Verweise aus 6.1a, nur mit einem Wort, das keine der bestehenden
Pruefungen kannte.
Aufgaben haben kein eigenes Label, ein {ref:} auf eine einzelne Aufgabe ist
also nicht moeglich. Verwiesen wird stattdessen auf Abschnitt plus
Aufgabentitel - und der ist stabil. Jedes Ziel wurde einzeln ueber die alte
Zaehlung bestimmt und am Zusammenhang geprueft.
Ein Fall war knifflig: "Uebung 6.7 (Wochendienstplan)" meinte die siebte
CP-SAT-Aufgabe der alten Zaehlung, also "Eigener Dienstplan" - die heute an
achter Stelle steht, weil in Phase 6.3 eine Aufgabe davor eingefuegt wurde.
Wer nur die Kapitelnummer angepasst haette, waere bei der falschen Aufgabe
gelandet.
--check kennt jetzt auch "Uebung"/"Übung". Gegengetestet.
PHASE 8.3: Dockerfile, zweistufig. Die erste Stufe uebersetzt die
Abhaengigkeiten in eine virtuelle Umgebung und braucht dafuer einen
Compiler, die zweite kopiert nur /opt/venv. Installiert werden die Gruppen
finance, large-scale, api und dev aus pyproject.toml; figures fehlt bewusst,
weil es zusaetzlich Graphviz verlangt.
Es wurde nicht behauptet, sondern gebaut. Ergebnis: 1,31 GB, und darin der
Installationstest mit allen drei Solver-Funktionstests bestanden, die 33
pytest-Tests bestanden und alle 69 netzfreien Programme fehlerfrei -
einschliesslich der drei aus 8.2, deren spawn-Isolation im Container ebenso
traegt wie ausserhalb.
Zwei Dinge, die der Bau gelehrt hat: libgomp1 fehlt im python:3.12-slim-Image
und wird von OR-Tools und HiGHS zur Laufzeit gebraucht (sonst
"libgomp.so.1: cannot open shared object file"). Und ein eigener Fehler:
USER kurs stand vor dem mkdir /buch/output, /buch gehoert root, der Bau
brach in der letzten Zeile ab. Beides steht jetzt als Kommentar im
Dockerfile.
Das Image fuehrt die Programme aus und baut das Buch nicht. Ein
.dockerignore haelt Website, PDF und Notebooks aus dem Build-Kontext. Und es
enthaelt ortools UND highspy, obwohl sie sich nicht gemeinsam importieren
lassen - der Konflikt wird zur Laufzeit durch getrennte Prozesse geloest,
nicht durch Weglassen.
Damit ist Phase 8 abgeschlossen und der Plan abgearbeitet.
Stand: 825 Querverweise, 76 Programme, 33 pytest-Tests, PDF 760 Seiten.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
862e92bc7b
commit
35cc0da166
22 changed files with 232 additions and 29 deletions
79
Dockerfile
Normal file
79
Dockerfile
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Kurs-Image zu "Optimierte Entscheidungsfindung mit Python".
|
||||
#
|
||||
# Was es ist: eine reproduzierbare Umgebung, in der alle Beispielprogramme
|
||||
# laufen - ohne dass jemand Solver, BLAS-Bibliotheken und Python-Versionen von
|
||||
# Hand zusammensuchen muss.
|
||||
#
|
||||
# Was es NICHT ist: eine Bauumgebung fuer das Buch. Das PDF braucht pandoc,
|
||||
# xelatex und inkscape, zusammen ueber ein Gigabyte. Wer das Buch selbst baut,
|
||||
# ist mit einer lokalen Installation besser bedient (siehe README.md).
|
||||
#
|
||||
# docker build -t or-mit-python .
|
||||
# docker run --rm or-mit-python Installationstest.py
|
||||
# docker run --rm -it or-mit-python # Python-Eingabe
|
||||
# docker run --rm -v "$PWD/ausgabe:/buch/output" or-mit-python Excel_Bruecke.py
|
||||
#
|
||||
# Zwei Stufen: Die erste baut die Abhaengigkeiten in eine virtuelle Umgebung
|
||||
# (und braucht dafuer Compiler), die zweite kopiert nur das Ergebnis. Das
|
||||
# spart im fertigen Image die gesamte Bauumgebung.
|
||||
|
||||
# --- Stufe 1: Abhaengigkeiten uebersetzen und einsammeln ---------------------
|
||||
FROM python:3.12-slim AS bau
|
||||
|
||||
# build-essential wird von Paketen gebraucht, die kein passendes Wheel
|
||||
# mitbringen. Bleibt in dieser Stufe und landet nie im fertigen Image.
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PIP_NO_CACHE_DIR=1 \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1
|
||||
RUN python -m venv /opt/venv
|
||||
ENV PATH="/opt/venv/bin:$PATH"
|
||||
|
||||
# Nur die Abhaengigkeitsbeschreibung kopieren, nicht den Quelltext: So bleibt
|
||||
# diese Schicht im Cache, solange sich die Abhaengigkeiten nicht aendern.
|
||||
WORKDIR /buch
|
||||
COPY pyproject.toml README.md ./
|
||||
|
||||
# Die Gruppen aus pyproject.toml. 'figures' fehlt bewusst - es dient dem
|
||||
# Neuerzeugen der Diagramme, wofuer zusaetzlich Graphviz noetig waere.
|
||||
#
|
||||
# ACHTUNG, gewollt: Das Image enthaelt ortools UND highspy, obwohl beide eine
|
||||
# eigene HiGHS-Kopie mitbringen und sich nicht gemeinsam importieren lassen.
|
||||
# Der Konflikt wird nicht durch Weglassen geloest, sondern zur Laufzeit durch
|
||||
# getrennte Prozesse (Kapitel Oekosystem). Ein Image, das nur eines von beiden
|
||||
# enthaelt, koennte die Haelfte der Beispiele nicht ausfuehren.
|
||||
RUN pip install ".[finance,large-scale,api,dev]"
|
||||
|
||||
# --- Stufe 2: das eigentliche Image -----------------------------------------
|
||||
FROM python:3.12-slim AS laufzeit
|
||||
|
||||
# libgomp1 wird von OR-Tools und HiGHS zur Laufzeit gebraucht (OpenMP) und ist
|
||||
# im slim-Image nicht enthalten. Ohne es scheitert der erste Solveraufruf mit
|
||||
# einem 'libgomp.so.1: cannot open shared object file'.
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
libgomp1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=bau /opt/venv /opt/venv
|
||||
ENV PATH="/opt/venv/bin:$PATH" \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
MPLBACKEND=Agg
|
||||
|
||||
# Kein root. Die Programme brauchen keine Rechte, und ein Kurs-Image, das als
|
||||
# root laeuft, ist eine schlechte Angewohnheit, die man weitergibt.
|
||||
RUN useradd --create-home --uid 1000 kurs
|
||||
WORKDIR /buch
|
||||
COPY --chown=kurs:kurs Operations_Research_mit_Python_Version_04_Programme/ ./
|
||||
|
||||
# Verzeichnis fuer erzeugte Dateien - als Volume einhaengbar, damit
|
||||
# Excel-Ausgaben und Diagramme den Container ueberleben. Angelegt wird es
|
||||
# VOR dem Benutzerwechsel, denn /buch gehoert root.
|
||||
RUN mkdir -p /buch/output && chown kurs:kurs /buch/output
|
||||
USER kurs
|
||||
|
||||
# Ohne Argument eine Python-Eingabeaufforderung, mit Argument das genannte
|
||||
# Programm: 'docker run --rm or-mit-python Rucksack.py'
|
||||
ENTRYPOINT ["python"]
|
||||
CMD []
|
||||
Loading…
Reference in a new issue