In diesem Beitrag wird beschrieben, wie man eine einfache Data Science App mit Frontend und Backend in Docker Container verpackt. Als Beispielanwedung verwende ich die hier beschriebene App.
Das Repository ist hier zu finden: https://github.com/gochxx/restapi
Docker Installation
Docker kann einfach über https://www.docker.com/products/docker-desktop/ heruntergeladen und installiert werden.
Docker Container erstellen
Zunächst erstellen wir einen einfachen Container, der lediglich die Flask App für die Bereitstellung der Rest-API enthält.
Dockerfile erstellen
# Verwende das offizielle Miniconda-Image als Basisimage
FROM continuumio/miniconda3
# Setze das Arbeitsverzeichnis im Container
WORKDIR /app
# Kopiere die Anforderungen (dependencies) in den Container
COPY app/requirements.txt app/
#VOLUME /app/data
# Kopiere die anderen Dateien
COPY app/app.py app/
COPY app/forecast.py app/
#COPY data /app/data
# Erstelle und aktiviere eine neue Conda-Umgebung und installiere die Abhängigkeiten
RUN conda create -y --name myenv python=3.10 && \
conda run -n myenv pip install --upgrade pip && \
conda run -n myenv pip install -r app/requirements.txt && \
conda clean -afy
# Stelle sicher, dass die Conda-Umgebung beim Containerstart aktiv ist
ENV PATH="/opt/conda/envs/myenv/bin:$PATH"
# Exponiere den Port, auf dem die Flask-Anwendung läuft
EXPOSE 5000
# Starte die Flask-Anwendung beim Ausführen des Containers
CMD ["/bin/bash", "-c", "source activate myenv && python app/app.py"]Container erstellen
docker build -t my-app .Container starten
Um den Container auszuführen benötigst Du dann folgenden Befehl:
docker run -p 5000:5000 my-appFalls der Container beim Starten Probleme hat, ist es manchmal hilfreich die interaktive Shell zu starten. Damit kann man sich direkt in den Container einloggen.
docker run -it my-app /bin/bashAlternativ kann der Container auch im Hintergrund gestartet werden. Dazu verwendet man diesen Befehl:
docker run -it my-app /bin/bash -dDie App läuft nun im Container und die Rest-API wird wie zuvor über den Port 5000 bereitgestellt.
Wir können das testen indem wir die Datei „run_app.py“ ausführen, die nun ebenso wie zuvor ohne Container funktioniert.
Container stoppen
Wenn der Container normal gestartet wurde, dann stoppt man ihn einfach mti CRTL+C
Wenn er im Hintergrund gestartet wurde dann muss man zunächst herausfinden wie der Container heißt. Alle laufenden Container anzeigen:
docker psUm den Container zu stoppen benötigt man die Container-ID oder den Namen. Dann verwendet man einen der folgenden beiden Befehl:
docker stop CONTAINER-ID
docker stop CONTAINER-NAMEMan kann auch alle Container stoppen:
docker stop $(docker ps -q)Wenn man den Container direkt entfernen möchte, dann geht das so:
docker stop CONTAINER-ID && docker rm CONTAINER-ID Docker Compose
Da Anwendung die wir erstellen wollen, verfügt nicht nur über die im Backend bereitgestellte REST-API, sondern hat zusätzlich auch noch ein Frontend. Im folgenden wird erklärt, wie man mit Docker-Compose einen weiteren Container erstellt, der das Frontend als HTML Seite bereitstellt. Dazu benötigen wir eine docker-compose.yml
version: '3.8'
services:
flask-app:
build:
context: .
dockerfile: Dockerfile
ports:
- "5000:5000"
networks:
- app-network
#volumes:
# - ./data:/app/data
frontend:
image: nginx:alpine
volumes:
- ./frontend:/usr/share/nginx/html
ports:
- "8001:80"
networks:
- app-network
depends_on:
- flask-app
proxy:
build:
./proxy
ports:
- "80:80"
networks:
- app-network
depends_on:
- flask-app
networks:
app-network:
driver: bridgeDocker Compose kann so gestartet werden:
docker-compose upFür einen Start im Hintergrund verwendet man wieder den Flag -d
docker-compose up -dWenn man Änderungen vorgenommen hat, kann man die Container so neu bauen:
docker-compose up --buildDa die HTML-Seite über den Port 80 bereitgestellt wird ist sie nun im Browser über http://localhost/ erreichbar.
Docker-Compose stoppen
docker-compose downUm alle Artefakte zu löschen, kann man diesen Befehl verwenden:
docker-compose down --volumes --remove-orphansDocker-Compose Debugging
Die Logs kann man so anzeigen lassen:
docker-compose logsDie Logs eines spezifischen Dienstes:
docker-compose logs flask-appFehlersuche im Container geht am besten mit der jeweiligen Container-Bash:
docker exec -it CONTAINERNAME /bin/sh