update
This commit is contained in:
@@ -0,0 +1,780 @@
|
||||
|
||||
---
|
||||
|
||||
# 🐳 Einführung in Docker
|
||||
|
||||
## 1. Was ist Docker?
|
||||
|
||||
Docker ist eine Plattform, mit der du **Container** erstellen, starten und verwalten kannst.
|
||||
Ein Container ist eine Art "leichtgewichtige virtuelle Maschine":
|
||||
|
||||
- Enthält **nur das Nötigste** (Programm, Abhängigkeiten, Bibliotheken).
|
||||
- Läuft isoliert, aber nutzt den Kernel des Host-Systems (kein eigener Kernel wie bei einer VM).
|
||||
- Ist **schneller** und **ressourcenschonender** als klassische VMs.
|
||||
|
||||
👉 Bildlich: Statt für jedes Programm einen eigenen PC (VM) aufzubauen, packst du nur das Programm in eine "Transportbox" (Container), die überall läuft, solange Docker installiert ist.
|
||||
|
||||
---
|
||||
|
||||
## 2. Vorteile und typische Anwendungsfälle
|
||||
|
||||
### Vorteile
|
||||
|
||||
- **Portabilität**: „Läuft auf meinem Rechner“ = „läuft auch auf Servern“.
|
||||
- **Isolierung**: Verschiedene Programme/Versionen stören sich nicht.
|
||||
- **Leichtgewicht**: Start in Sekunden statt Minuten wie bei VMs.
|
||||
- **Reproduzierbarkeit**: Gleiche Umgebung für Entwicklung, Test und Produktion.
|
||||
- **Einfache Verteilung**: Images können über Docker Hub oder private Registries geteilt werden.
|
||||
|
||||
### Typische Anwendungsfälle
|
||||
|
||||
- 🚀 **Entwicklung**: Z. B. [[Python]] 3.10 testen, obwohl auf dem System Python 3.12 läuft.
|
||||
- 🗄️ **Datenbanken**: [[MySQL]], PostgreSQL, Redis, MongoDB zum Testen ohne Installation.
|
||||
- 🌐 **Web-Apps**: Schnell mal eine fertige Anwendung ausprobieren (WordPress, Nextcloud, GitLab etc.).
|
||||
- 🧪 **Testing**: Mehrere Umgebungen simulieren (verschiedene OS, Bibliotheksversionen).
|
||||
- 📦 **Deployment**: Gleiche App auf mehreren Servern identisch bereitstellen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Hauptfunktionalitäten von Docker
|
||||
|
||||
- **Docker Engine**: Herzstück, das Container ausführt.
|
||||
- **Docker Images**: Baupläne (Templates) für Container (z. B. Python 3.12 + Flask).
|
||||
- **Docker Containers**: Laufende Instanzen von Images.
|
||||
- **Docker Hub/Registry**: Cloud-Marktplatz für fertige Images.
|
||||
- **Docker Compose**: Orchestrierung mehrerer Container (z. B. App + DB + Cache).
|
||||
|
||||
---
|
||||
|
||||
## 4. Installation unter Linux (Beispiel: Ubuntu/Debian)
|
||||
|
||||
```bash
|
||||
# 1. Alte Versionen entfernen
|
||||
sudo apt-get remove docker docker-engine docker.io containerd runc
|
||||
|
||||
# 2. Repository vorbereiten
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates curl gnupg
|
||||
|
||||
# Docker GPG-Key hinzufügen
|
||||
sudo install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
|
||||
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
|
||||
# Repository einrichten
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
|
||||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# 3. Docker installieren
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
# 4. Testen
|
||||
sudo docker run hello-world
|
||||
```
|
||||
|
||||
👉 Danach kannst du optional dich in die `docker`-Gruppe aufnehmen (sonst musst du immer `sudo` schreiben):
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
# Abmelden/neu anmelden, damit es wirkt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Erste Schritte in der Praxis
|
||||
|
||||
### Beispiel 1: Linux — Container starten
|
||||
|
||||
```bash
|
||||
# Einen Ubuntu-Container starten (interaktiv)
|
||||
docker run -it ubuntu bash
|
||||
|
||||
# Danach bist du im Container:
|
||||
root@<id>:/# cat /etc/os-release
|
||||
```
|
||||
|
||||
Wenn du rausgehst (`exit`), bleibt der Container gespeichert.
|
||||
|
||||
---
|
||||
|
||||
### Beispiel 2: Linux — Nginx-Webserver starten
|
||||
|
||||
```bash
|
||||
# Nginx starten, Port 8080 weiterleiten
|
||||
docker run -d -p 8080:80 nginx
|
||||
|
||||
# Nun im Browser: http://localhost:8080
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Beispiel 3: Python im Container
|
||||
|
||||
Nehmen wir an, du willst ein Python-Skript in einer isolierten Umgebung ausführen.
|
||||
|
||||
**hello.py**
|
||||
|
||||
```python
|
||||
print("Hello from Dockerized Python!")
|
||||
```
|
||||
|
||||
**Dockerfile**
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Skript ins Image kopieren
|
||||
COPY hello.py /app/hello.py
|
||||
|
||||
# Arbeitsverzeichnis setzen
|
||||
WORKDIR /app
|
||||
|
||||
# Default-Befehl
|
||||
CMD ["python", "hello.py"]
|
||||
```
|
||||
|
||||
**Bauen und starten**
|
||||
|
||||
```bash
|
||||
# Image bauen
|
||||
docker build -t mypythonapp .
|
||||
|
||||
# Container starten
|
||||
docker run --rm mypythonapp
|
||||
```
|
||||
|
||||
Ausgabe:
|
||||
|
||||
```
|
||||
Hello from Dockerized Python!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Beispiel 4: Python mit externer Bibliothek
|
||||
|
||||
```python
|
||||
# requirements.txt
|
||||
flask==3.0.0
|
||||
```
|
||||
|
||||
**app.py**
|
||||
|
||||
```python
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello, Docker!"
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=5000)
|
||||
```
|
||||
|
||||
**Dockerfile**
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
COPY app.py .
|
||||
|
||||
CMD ["python", "app.py"]
|
||||
```
|
||||
|
||||
**Starten**
|
||||
|
||||
```bash
|
||||
docker build -t flaskapp .
|
||||
docker run -d -p 5000:5000 flaskapp
|
||||
```
|
||||
|
||||
👉 Browser öffnen: `http://localhost:5000`
|
||||
|
||||
---
|
||||
|
||||
## 6. Nützliche Docker-Befehle (Cheatsheet)
|
||||
|
||||
- `docker ps` – laufende Container
|
||||
- `docker ps -a` – alle Container (inkl. gestoppter)
|
||||
- `docker images` – vorhandene Images
|
||||
- `docker stop <id>` – Container stoppen
|
||||
- `docker rm <id>` – Container löschen
|
||||
- `docker rmi <image>` – Image löschen
|
||||
- `docker exec -it <id> bash` – in Container einsteigen
|
||||
|
||||
---
|
||||
|
||||
✅ Damit hast du einen vollständigen Überblick über Docker:
|
||||
|
||||
- **Grundidee**
|
||||
- **Vorteile/Anwendungsfälle**
|
||||
- **Installation**
|
||||
- **Praxis mit Linux und Python**
|
||||
|
||||
---
|
||||
# Anwendungsbeispiel
|
||||
# 🐳 Docker Anwendungsbeispiel - Detaillierte Erklärung für Einsteiger
|
||||
|
||||
## 📚 Was ist Docker überhaupt?
|
||||
|
||||
**Docker** ist wie ein **"Umzugskarton für Software"**:
|
||||
- Stell Dir vor, Du willst Deine App an einen Freund verschicken
|
||||
- Statt nur den Code zu senden, packst Du **alles** ein: Code, Python, alle Bibliotheken, Konfiguration
|
||||
- Dein Freund öffnet den "Karton" (Container) und alles läuft sofort - egal welches Betriebssystem er hat
|
||||
|
||||
---
|
||||
|
||||
## 📁 Projektstruktur mit Erklärungen
|
||||
|
||||
```
|
||||
python-docker-project/
|
||||
├── app/ # 📂 Unser Python-Code
|
||||
│ ├── __init__.py # (macht 'app' zu einem Python-Paket)
|
||||
│ ├── main.py # Hauptprogramm
|
||||
│ ├── data_processor.py # Modul für Datenverarbeitung
|
||||
│ └── database.py # Modul für Datenbankzugriff
|
||||
├── input/ # 📁 Hier liegen die Input-Dateien (vom Host)
|
||||
│ └── sample_data.csv # Beispieldatei
|
||||
├── output/ # 📁 Hier kommen verarbeitete Dateien rein
|
||||
├── requirements.txt # 📝 Liste aller Python-Pakete die wir brauchen
|
||||
├── Dockerfile # 🐳 "Bauanleitung" für unseren Container
|
||||
├── docker-compose.yml # 🎼 "Dirigent" für mehrere Container
|
||||
└── .env # 🔐 Geheime Einstellungen (Passwörter etc.)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐍 Python-Code (wie gewohnt)
|
||||
|
||||
### **requirements.txt** - "Einkaufsliste" für Python-Pakete
|
||||
```txt
|
||||
# 🛒 Diese Pakete braucht unser Programm
|
||||
pandas==2.1.4 # Für Excel/CSV-Verarbeitung
|
||||
psycopg2-binary==2.9.9 # Um mit PostgreSQL zu sprechen
|
||||
python-dotenv==1.0.0 # Um .env-Dateien zu lesen
|
||||
sqlalchemy==2.0.23 # Einfache Datenbankanbindung
|
||||
```
|
||||
|
||||
**💡 Warum brauche ich das?**
|
||||
- Ohne Docker müsstest Du auf jedem PC manuell `pip install pandas` etc. machen
|
||||
- Mit Docker installiert sich das automatisch im Container
|
||||
|
||||
### **app/main.py** - Unser Hauptprogramm
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🎯 Das macht unser Programm:
|
||||
1. Schaut in /app/input nach CSV-Dateien
|
||||
2. Verarbeitet sie (quadriert Werte, etc.)
|
||||
3. Speichert Ergebnis in PostgreSQL-Datenbank
|
||||
4. Exportiert auch als CSV in /app/output
|
||||
"""
|
||||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from .data_processor import DataProcessor
|
||||
from .database import DatabaseManager
|
||||
|
||||
def main():
|
||||
print("🚀 Starte Data Processing Pipeline...")
|
||||
|
||||
# 📁 Diese Pfade sind INSIDE dem Container!
|
||||
input_dir = Path("/app/input") # Gemountet von Host ./input/
|
||||
output_dir = Path("/app/output") # Gemountet von Host ./output/
|
||||
output_dir.mkdir(exist_ok=True)
|
||||
|
||||
# 🗄️ Verbindung zur Datenbank (anderer Container!)
|
||||
db_manager = DatabaseManager()
|
||||
processor = DataProcessor(db_manager)
|
||||
|
||||
# 📊 Alle CSV-Dateien finden und verarbeiten
|
||||
csv_files = list(input_dir.glob("*.csv"))
|
||||
|
||||
if not csv_files:
|
||||
print("❌ Keine CSV-Dateien im Input-Verzeichnis gefunden!")
|
||||
return
|
||||
|
||||
for csv_file in csv_files:
|
||||
print(f"📄 Verarbeite: {csv_file.name}")
|
||||
|
||||
# 1️⃣ Daten aus CSV laden und verarbeiten
|
||||
result_data = processor.process_file(csv_file)
|
||||
|
||||
# 2️⃣ In PostgreSQL-Container speichern
|
||||
processor.save_to_database(result_data, csv_file.stem)
|
||||
|
||||
# 3️⃣ Als neue CSV-Datei exportieren
|
||||
output_file = output_dir / f"processed_{csv_file.name}"
|
||||
result_data.to_csv(output_file, index=False)
|
||||
print(f"💾 Gespeichert als: {output_file}")
|
||||
|
||||
print("✅ Pipeline abgeschlossen!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
### **app/database.py** - Spricht mit der Datenbank
|
||||
```python
|
||||
import os
|
||||
import pandas as pd
|
||||
from sqlalchemy import create_engine, text
|
||||
|
||||
class DatabaseManager:
|
||||
def __init__(self):
|
||||
# 🔌 Diese Werte kommen aus der docker-compose.yml!
|
||||
self.host = os.getenv('DB_HOST', 'postgres') # Name des DB-Containers!
|
||||
self.port = os.getenv('DB_PORT', '5432')
|
||||
self.database = os.getenv('DB_NAME', 'dataprocessing')
|
||||
self.user = os.getenv('DB_USER', 'postgres')
|
||||
self.password = os.getenv('DB_PASSWORD', 'password')
|
||||
|
||||
# 🌐 Connection String - wie eine Adresse zur Datenbank
|
||||
self.connection_string = (
|
||||
f"postgresql://{self.user}:{self.password}@"
|
||||
f"{self.host}:{self.port}/{self.database}"
|
||||
)
|
||||
|
||||
self.engine = None
|
||||
self._connect()
|
||||
|
||||
def _connect(self):
|
||||
"""Verbindung zur Datenbank herstellen"""
|
||||
try:
|
||||
self.engine = create_engine(self.connection_string)
|
||||
# 🏓 Kurzer Test: "Hallo Datenbank!"
|
||||
with self.engine.connect() as conn:
|
||||
conn.execute(text("SELECT 1"))
|
||||
print("✅ Datenbankverbindung erfolgreich")
|
||||
except Exception as e:
|
||||
print(f"❌ Datenbankverbindung fehlgeschlagen: {e}")
|
||||
raise
|
||||
|
||||
def save_dataframe(self, df: pd.DataFrame, table_name: str):
|
||||
"""Speichert DataFrame als Tabelle in PostgreSQL"""
|
||||
df.to_sql(
|
||||
name=table_name,
|
||||
con=self.engine,
|
||||
if_exists='replace', # Überschreibt existierende Tabelle
|
||||
index=False
|
||||
)
|
||||
```
|
||||
|
||||
*(Die anderen Python-Dateien bleiben gleich)*
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Dockerfile - "Bauanleitung" für unseren Container
|
||||
|
||||
```dockerfile
|
||||
# 🏗️ SCHRITT 1: Basis-Image wählen
|
||||
# Das ist wie ein "Rohbau" - Linux + Python sind schon installiert
|
||||
FROM python:3.11-slim
|
||||
|
||||
# 🛠️ SCHRITT 2: System-Tools installieren
|
||||
# Wir brauchen gcc und libpq-dev für PostgreSQL-Verbindung
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
libpq-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 💡 WARUM: psycopg2 (PostgreSQL-Driver) braucht diese Tools zum Kompilieren
|
||||
|
||||
# 📂 SCHRITT 3: Arbeitsverzeichnis setzen
|
||||
WORKDIR /app
|
||||
# Das ist wie "cd /app" - alle folgenden Befehle laufen hier
|
||||
|
||||
# 📦 SCHRITT 4: Python-Pakete installieren
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
# 💡 WARUM separat? Docker cached diesen Layer - muss nur neu gebaut werden wenn requirements.txt ändert
|
||||
|
||||
# 📋 SCHRITT 5: Unseren Code ins Container kopieren
|
||||
COPY app/ ./app/
|
||||
# Kopiert alles aus Host-Ordner "app/" nach Container "/app/app/"
|
||||
|
||||
# 📁 SCHRITT 6: Verzeichnisse erstellen
|
||||
RUN mkdir -p /app/input /app/output
|
||||
# Diese werden später durch Volume-Mounts "überschrieben"
|
||||
|
||||
# ⚙️ SCHRITT 7: Umgebungsvariablen setzen
|
||||
ENV PYTHONPATH=/app # Python findet unsere Module
|
||||
ENV PYTHONUNBUFFERED=1 # Print-Ausgaben erscheinen sofort
|
||||
|
||||
# 🚀 SCHRITT 8: Was soll beim Container-Start passieren?
|
||||
CMD ["python", "-m", "app.main"]
|
||||
# Startet unser Hauptprogramm
|
||||
```
|
||||
|
||||
**🤔 Was passiert beim `docker build`?**
|
||||
1. Docker lädt `python:3.11-slim` herunter (falls nicht da)
|
||||
2. Installiert gcc und PostgreSQL-Tools
|
||||
3. Kopiert `requirements.txt` und installiert Python-Pakete
|
||||
4. Kopiert unseren Code rein
|
||||
5. Setzt Umgebungsvariablen
|
||||
6. **Ergebnis:** Ein fertiger Container mit allem was wir brauchen!
|
||||
|
||||
---
|
||||
|
||||
## 🎼 docker-compose.yml - "Dirigent" für mehrere Container
|
||||
|
||||
```yaml
|
||||
# 🎯 docker-compose orchestriert MEHRERE Container gleichzeitig
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# 🗄️ CONTAINER 1: PostgreSQL-Datenbank
|
||||
postgres:
|
||||
image: postgres:15 # Fertiges PostgreSQL-Image von Docker Hub
|
||||
environment: # Umgebungsvariablen für PostgreSQL
|
||||
POSTGRES_DB: dataprocessing # Name der Datenbank die erstellt wird
|
||||
POSTGRES_USER: postgres # Benutzername
|
||||
POSTGRES_PASSWORD: password # 🔐 Passwort (in Produktion geheimer!)
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data # 💾 Daten persistent speichern
|
||||
- ./db_init:/docker-entrypoint-initdb.d # 📂 Optional: SQL-Skripts beim Start
|
||||
ports:
|
||||
- "5432:5432" # Port freigeben (Host:Container)
|
||||
networks:
|
||||
- app_network # 🌐 Internes Netzwerk für Container-Kommunikation
|
||||
|
||||
# 🐍 CONTAINER 2: Unsere Python-Anwendung
|
||||
python_app:
|
||||
build: . # 🏗️ Baue Container aus Dockerfile in diesem Verzeichnis
|
||||
environment: # Diese Variablen kann unser Python-Code lesen
|
||||
DB_HOST: postgres # ❗ WICHTIG: Name des DB-Containers (nicht localhost!)
|
||||
DB_PORT: 5432
|
||||
DB_NAME: dataprocessing
|
||||
DB_USER: postgres
|
||||
DB_PASSWORD: password
|
||||
volumes: # 📂 Verbinde Host-Verzeichnisse mit Container
|
||||
- ./input:/app/input:ro # Host ./input → Container /app/input (read-only)
|
||||
- ./output:/app/output # Host ./output → Container /app/output (read-write)
|
||||
depends_on: # ⏱️ Warte bis postgres-Container läuft
|
||||
- postgres
|
||||
networks:
|
||||
- app_network # 🌐 Gleiches Netzwerk = können miteinander sprechen
|
||||
restart: unless-stopped # 🔄 Automatisch neu starten bei Absturz
|
||||
|
||||
# 🌐 CONTAINER 3: pgAdmin (Web-Interface für PostgreSQL)
|
||||
pgadmin:
|
||||
image: dpage/pgadmin4:8
|
||||
environment:
|
||||
PGADMIN_DEFAULT_EMAIL: admin@example.com
|
||||
PGADMIN_DEFAULT_PASSWORD: admin
|
||||
ports:
|
||||
- "8080:80" # 🌐 Zugriff via http://localhost:8080
|
||||
depends_on:
|
||||
- postgres
|
||||
networks:
|
||||
- app_network
|
||||
|
||||
# 💾 VOLUMES: Persistente Datenspeicherung
|
||||
volumes:
|
||||
postgres_data: # Docker verwaltet diesen Speicher automatisch
|
||||
# 💡 Auch wenn Container gelöscht wird, bleiben Daten erhalten
|
||||
|
||||
# 🌐 NETWORKS: Virtuelle Netzwerke für Container-Kommunikation
|
||||
networks:
|
||||
app_network:
|
||||
driver: bridge # Standard-Netzwerk-Typ
|
||||
# 💡 Alle Container in diesem Netzwerk können sich über Namen erreichen
|
||||
```
|
||||
|
||||
**🤔 Warum docker-compose?**
|
||||
- **Ohne compose:** `docker run postgres`, dann `docker run python_app` - sehr umständlich!
|
||||
- **Mit compose:** Ein Befehl (`docker-compose up`) startet ALLES automatisch
|
||||
- **Networks:** Container können sich über Namen finden (`postgres` statt IP-Adresse)
|
||||
- **Volumes:** Daten gehen nicht verloren beim Container-Neustart
|
||||
|
||||
---
|
||||
|
||||
## 🔧 .env - Geheime Konfiguration
|
||||
|
||||
```env
|
||||
# 🔐 Sensible Daten sollten NICHT in docker-compose.yml stehen
|
||||
# Diese Datei wird von docker-compose automatisch gelesen
|
||||
|
||||
# Datenbankverbindung
|
||||
DB_HOST=postgres
|
||||
DB_PORT=5432
|
||||
DB_NAME=dataprocessing
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=password # ❗ In Produktion: sicheres Passwort!
|
||||
|
||||
# Python-Einstellungen
|
||||
PYTHONPATH=/app
|
||||
PYTHONUNBUFFERED=1
|
||||
```
|
||||
|
||||
**💡 Wichtig:** Die `.env`-Datei niemals in Git committen! (→ `.gitignore`)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Beispiel-Daten
|
||||
|
||||
### **input/sample_data.csv**
|
||||
```csv
|
||||
id,name,value,category
|
||||
1,Item A,10,electronics
|
||||
2,Item B,25,clothing
|
||||
3,Item C,15,electronics
|
||||
4,Item D,30,books
|
||||
5,Item E,8,clothing
|
||||
```
|
||||
|
||||
**💡 Das ist eine normale CSV-Datei auf Deinem Host-PC**
|
||||
- Liegt in `./input/sample_data.csv`
|
||||
- Wird in den Container als `/app/input/sample_data.csv` "gemountet"
|
||||
- Unser Python-Code kann sie lesen, als wäre sie im Container
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Schritt-für-Schritt Anleitung
|
||||
|
||||
### **1. Projekt erstellen**
|
||||
```bash
|
||||
# Verzeichnis erstellen
|
||||
mkdir python-docker-project
|
||||
cd python-docker-project
|
||||
|
||||
# Struktur erstellen
|
||||
mkdir -p app input output
|
||||
touch requirements.txt Dockerfile docker-compose.yml .env
|
||||
touch app/__init__.py app/main.py app/data_processor.py app/database.py
|
||||
```
|
||||
|
||||
### **2. Code schreiben**
|
||||
- Alle Dateien wie oben gezeigt erstellen und befüllen
|
||||
|
||||
### **3. Container bauen und starten**
|
||||
```bash
|
||||
# Alle Container bauen und starten
|
||||
docker-compose up --build
|
||||
|
||||
# 🔍 Was passiert:
|
||||
# 1. Docker baut unseren Python-Container (aus Dockerfile)
|
||||
# 2. Lädt PostgreSQL-Image herunter
|
||||
# 3. Lädt pgAdmin-Image herunter
|
||||
# 4. Erstellt Netzwerk "app_network"
|
||||
# 5. Startet postgres-Container
|
||||
# 6. Startet python_app-Container (wartet auf postgres)
|
||||
# 7. Startet pgAdmin-Container
|
||||
```
|
||||
|
||||
### **4. Überprüfen ob alles läuft**
|
||||
```bash
|
||||
# Laufende Container anzeigen
|
||||
docker-compose ps
|
||||
|
||||
# Logs ansehen
|
||||
docker-compose logs python_app
|
||||
docker-compose logs postgres
|
||||
|
||||
# In pgAdmin einloggen: http://localhost:8080
|
||||
# Email: admin@example.com, Passwort: admin
|
||||
```
|
||||
|
||||
### **5. Neue Daten verarbeiten**
|
||||
```bash
|
||||
# Neue CSV-Datei ins input-Verzeichnis kopieren
|
||||
cp neue_daten.csv input/
|
||||
|
||||
# Python-App neu starten um neue Dateien zu verarbeiten
|
||||
docker-compose restart python_app
|
||||
|
||||
# Ergebnis ansehen
|
||||
ls -la output/
|
||||
```
|
||||
|
||||
### **6. System stoppen**
|
||||
```bash
|
||||
# Alle Container stoppen
|
||||
docker-compose down
|
||||
|
||||
# Container stoppen UND Daten löschen (Vorsicht!)
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Docker-Befehle erklärt
|
||||
|
||||
### **Grundlegende Container-Befehle**
|
||||
```bash
|
||||
# 📋 Alle laufenden Container anzeigen
|
||||
docker ps
|
||||
|
||||
# 📋 Alle Container anzeigen (auch gestoppte)
|
||||
docker ps -a
|
||||
|
||||
# 🔍 Container-Logs ansehen
|
||||
docker logs <container-name>
|
||||
|
||||
# 🔑 In laufenden Container "einsteigen"
|
||||
docker exec -it <container-name> bash
|
||||
|
||||
# 🗑️ Container stoppen
|
||||
docker stop <container-name>
|
||||
|
||||
# 🗑️ Container löschen
|
||||
docker rm <container-name>
|
||||
```
|
||||
|
||||
### **Image-Befehle**
|
||||
```bash
|
||||
# 📋 Alle Images anzeigen
|
||||
docker images
|
||||
|
||||
# 🏗️ Image aus Dockerfile bauen
|
||||
docker build -t mein-python-app .
|
||||
|
||||
# 🗑️ Image löschen
|
||||
docker rmi <image-name>
|
||||
|
||||
# 🧹 Unbenutzte Images löschen
|
||||
docker image prune
|
||||
```
|
||||
|
||||
### **docker-compose-Befehle**
|
||||
```bash
|
||||
# 🚀 Alle Services starten
|
||||
docker-compose up
|
||||
|
||||
# 🚀 Im Hintergrund starten
|
||||
docker-compose up -d
|
||||
|
||||
# 🏗️ Images neu bauen und starten
|
||||
docker-compose up --build
|
||||
|
||||
# 🔄 Einzelnen Service neu starten
|
||||
docker-compose restart python_app
|
||||
|
||||
# 📋 Status aller Services
|
||||
docker-compose ps
|
||||
|
||||
# 🔍 Logs aller Services
|
||||
docker-compose logs
|
||||
|
||||
# 🔍 Logs eines bestimmten Service
|
||||
docker-compose logs python_app
|
||||
|
||||
# 📈 Live-Logs verfolgen
|
||||
docker-compose logs -f python_app
|
||||
|
||||
# 🔑 In Container einsteigen
|
||||
docker-compose exec python_app bash
|
||||
docker-compose exec postgres psql -U postgres -d dataprocessing
|
||||
|
||||
# ⏹️ Alle Services stoppen
|
||||
docker-compose down
|
||||
|
||||
# 🗑️ Services stoppen und Volumes löschen
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Die wichtigsten Docker-Konzepte
|
||||
|
||||
### **1. Images vs Container**
|
||||
- **Image** = "Bauplan" (wie ein Kuchenrezept)
|
||||
- **Container** = "Laufende Instanz" (wie ein gebackener Kuchen)
|
||||
- Ein Image kann viele Container erstellen
|
||||
|
||||
### **2. Volumes**
|
||||
```yaml
|
||||
volumes:
|
||||
- ./input:/app/input # Host-Verzeichnis → Container-Verzeichnis
|
||||
```
|
||||
- **Warum?** Container-Dateisystem ist temporär
|
||||
- **Volume** = persistenter Speicher der überlebt
|
||||
|
||||
### **3. Networks**
|
||||
- Container in gleichem Netzwerk können sich über Namen erreichen
|
||||
- `python_app` kann `postgres` kontaktieren (nicht IP-Adresse!)
|
||||
|
||||
### **4. Environment Variables**
|
||||
```yaml
|
||||
environment:
|
||||
DB_HOST: postgres # Diese Variable kann Python-Code lesen
|
||||
```
|
||||
|
||||
### **5. Ports**
|
||||
```yaml
|
||||
ports:
|
||||
- "8080:80" # Host-Port : Container-Port
|
||||
```
|
||||
- Container-Port 80 wird auf Host-Port 8080 freigegeben
|
||||
- Zugriff: `http://localhost:8080`
|
||||
|
||||
---
|
||||
|
||||
## ❓ Häufige Anfänger-Probleme
|
||||
|
||||
### **Problem 1: "Connection refused" zur Datenbank**
|
||||
```
|
||||
❌ FALSCH: DB_HOST=localhost
|
||||
✅ RICHTIG: DB_HOST=postgres
|
||||
```
|
||||
- In Docker ist `localhost` der Container selbst
|
||||
- Verwende den Service-Namen aus `docker-compose.yml`
|
||||
|
||||
### **Problem 2: "File not found"**
|
||||
```
|
||||
❌ FALSCH: input_dir = Path("./input")
|
||||
✅ RICHTIG: input_dir = Path("/app/input")
|
||||
```
|
||||
- Pfade sind INSIDE dem Container, nicht auf dem Host
|
||||
|
||||
### **Problem 3: "Module not found"**
|
||||
```
|
||||
❌ FALSCH: Umgebungsvariable vergessen
|
||||
✅ RICHTIG: ENV PYTHONPATH=/app in Dockerfile
|
||||
```
|
||||
|
||||
### **Problem 4: Änderungen nicht sichtbar**
|
||||
```bash
|
||||
# Nach Code-Änderungen Container neu bauen:
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
### **Problem 5: Port bereits belegt**
|
||||
```
|
||||
❌ Error: Port 5432 already in use
|
||||
✅ Lösung: Anderen Port verwenden: "5433:5432"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Zusammenfassung - Was macht was?
|
||||
|
||||
| Datei/Komponente | Was es macht | Warum wichtig |
|
||||
|------------------|--------------|---------------|
|
||||
| **Dockerfile** | "Bauanleitung" für Python-Container | Definiert was IN den Container kommt |
|
||||
| **docker-compose.yml** | Orchestriert mehrere Container | Ein Befehl startet alles |
|
||||
| **requirements.txt** | Liste der Python-Pakete | Automatische Installation |
|
||||
| **.env** | Geheime Konfiguration | Passwörter nicht in Code |
|
||||
| **volumes** | Datenaustausch Host ↔ Container | Input/Output-Dateien |
|
||||
| **networks** | Container-Kommunikation | python_app kann postgres erreichen |
|
||||
| **ports** | Zugriff von außen | Web-Interface erreichbar |
|
||||
|
||||
**🚀 Mit einem Befehl hast Du:**
|
||||
- ✅ Python-Umgebung mit allen Paketen
|
||||
- ✅ PostgreSQL-Datenbank
|
||||
- ✅ Web-Interface für DB
|
||||
- ✅ Automatische File-Verarbeitung
|
||||
- ✅ Persistente Datenspeicherung
|
||||
|
||||
**Das ist die Macht von Docker! 🐳**
|
||||
Reference in New Issue
Block a user