undate Docker + workflows
Some checks failed
Build and Push Docker Image / build (push) Failing after 48s

This commit is contained in:
2025-11-19 14:27:38 +01:00
parent 37202aa2aa
commit b348d11764
4 changed files with 86 additions and 23 deletions

13
.dockerignore Normal file
View File

@@ -0,0 +1,13 @@
pycache
*.pyc
*.pyo
*.pyd
.Python
env
venv
.venv
*.db
*.sqlite3
hangman_data/
.git
.gitignore

View File

@@ -0,0 +1,42 @@
name: Build and Push Docker Image
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: git.out.jafre.li
# ${{ gitea.actor }} ist der User, der den Push macht
username: ${{ gitea.actor }}
# ${{ secrets.GITHUB_TOKEN }} wird von Gitea automatisch bereitgestellt
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: git.out.jafre.li/${{ gitea.repository }}
tags: |
type=raw,value=latest
type=sha,format=long
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -1,30 +1,32 @@
# 1. Basis-Image (entspricht pyproject.toml)
# 1. Basis-Image
FROM python:3.12-slim
# 2. Setze den Arbeitsordner
WORKDIR /app
# 3. Installiere uv (dies ist das einzige Paket, das wir mit pip installieren müssen)
# uv ist für die Installation der anderen Pakete notwendig
# 3. Environment Variables setzen (verhindert .pyc Dateien und Pufferung)
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# 4. Installiere uv
RUN pip install --no-cache-dir uv
# 4. Kopiere nur die Konfigurationsdatei für den Installationsschritt
# Das nutzt den Docker Build Cache, wenn sich nur der Code ändert.
# 5. Dependencies installieren
COPY pyproject.toml .
# 5. Installiere die Abhängigkeiten aus der pyproject.toml mit uv
# Der Punkt '.' bedeutet "installiere die Abhängigkeiten für das aktuelle Verzeichnis,
# welches die pyproject.toml enthält". --system ist gut im Container.
# --system flag installiert in das globale Python des Containers
RUN uv pip install --system .
# 6. Kopiere den Rest des Codes (inkl. main.py)
# 6. Kopiere den Code
COPY . .
# 7. Expose Port (optional, da der Port im CMD-Befehl gebunden wird, aber gute Doku)
# 7. Erstelle einen Ordner für die persistente Datenbank
RUN mkdir -p /app/data
# 8. Expose Port
EXPOSE 80
# 8. Starte die Anwendung beim Container-Start (CMD, nicht RUN!)
# Wir nutzen Gunicorn als Master-Prozess und starten es direkt.
# Der 'uv run'-Befehl ist hier nicht notwendig, da gunicorn bereits über 'uv pip install'
# im Systempfad installiert wurde.
# 9. Startbefehl
# Wir setzen den DB_PATH standardmäßig auf den data Ordner, falls er nicht überschrieben wird
ENV DB_PATH="/app/data/hangman.db"
CMD ["gunicorn", "main:app", "--bind", "0.0.0.0:80", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker"]

22
main.py
View File

@@ -1,17 +1,24 @@
import sqlite3
import os
from fastapi import FastAPI
# 📁 Dateiname der Datenbank
DB_NAME = "hangman.db"
# 📁 Konfiguration: Lese Pfad aus ENV oder nutze Standard
# Im Docker Container setzen wir dies später auf /app/data/hangman.db
DB_PATH = os.getenv("DB_PATH", "hangman.db")
# 🛠️ Datenbank-Hilfsfunktionen
def get_db_connection():
"""Erstellt eine Verbindung zur SQLite-Datenbank."""
conn = sqlite3.connect(DB_NAME)
# Prüfen, ob das Verzeichnis existiert, falls es ein absoluter Pfad ist
directory = os.path.dirname(DB_PATH)
if directory and not os.path.exists(directory):
os.makedirs(directory, exist_ok=True)
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn
# 💡 Initialisiere die FastAPI-Anwendung (ohne Lifespan/Init-Logik)
# 💡 Initialisiere die FastAPI-Anwendung
app = FastAPI()
@app.get("/random_word")
@@ -31,8 +38,7 @@ def get_random_word():
if result:
return {"word": result["word"]}
else:
return {"error": "Keine Wörter in der Datenbank gefunden (Bitte init.py ausführen)."}
return {"error": f"Keine Wörter in {DB_PATH} gefunden."}
except sqlite3.OperationalError:
# Fängt den Fall ab, dass die Tabelle noch nicht existiert
return {"error": "Datenbankfehler: Wurde init.py ausgeführt?"}
except sqlite3.OperationalError as e:
return {"error": f"Datenbankfehler bei {DB_PATH}: {str(e)}"}