undate Docker + workflows
Some checks failed
Build and Push Docker Image / build (push) Failing after 48s
Some checks failed
Build and Push Docker Image / build (push) Failing after 48s
This commit is contained in:
13
.dockerignore
Normal file
13
.dockerignore
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
pycache
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
.Python
|
||||||
|
env
|
||||||
|
venv
|
||||||
|
.venv
|
||||||
|
*.db
|
||||||
|
*.sqlite3
|
||||||
|
hangman_data/
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
42
.gitea/workflows/build-push.yaml
Normal file
42
.gitea/workflows/build-push.yaml
Normal 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 }}
|
||||||
32
Dockerfile
32
Dockerfile
@@ -1,30 +1,32 @@
|
|||||||
# 1. Basis-Image (entspricht pyproject.toml)
|
# 1. Basis-Image
|
||||||
FROM python:3.12-slim
|
FROM python:3.12-slim
|
||||||
|
|
||||||
# 2. Setze den Arbeitsordner
|
# 2. Setze den Arbeitsordner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# 3. Installiere uv (dies ist das einzige Paket, das wir mit pip installieren müssen)
|
# 3. Environment Variables setzen (verhindert .pyc Dateien und Pufferung)
|
||||||
# uv ist für die Installation der anderen Pakete notwendig
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# 4. Installiere uv
|
||||||
RUN pip install --no-cache-dir uv
|
RUN pip install --no-cache-dir uv
|
||||||
|
|
||||||
# 4. Kopiere nur die Konfigurationsdatei für den Installationsschritt
|
# 5. Dependencies installieren
|
||||||
# Das nutzt den Docker Build Cache, wenn sich nur der Code ändert.
|
|
||||||
COPY pyproject.toml .
|
COPY pyproject.toml .
|
||||||
|
# --system flag installiert in das globale Python des Containers
|
||||||
# 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.
|
|
||||||
RUN uv pip install --system .
|
RUN uv pip install --system .
|
||||||
|
|
||||||
# 6. Kopiere den Rest des Codes (inkl. main.py)
|
# 6. Kopiere den Code
|
||||||
COPY . .
|
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
|
EXPOSE 80
|
||||||
|
|
||||||
# 8. Starte die Anwendung beim Container-Start (CMD, nicht RUN!)
|
# 9. Startbefehl
|
||||||
# Wir nutzen Gunicorn als Master-Prozess und starten es direkt.
|
# Wir setzen den DB_PATH standardmäßig auf den data Ordner, falls er nicht überschrieben wird
|
||||||
# Der 'uv run'-Befehl ist hier nicht notwendig, da gunicorn bereits über 'uv pip install'
|
ENV DB_PATH="/app/data/hangman.db"
|
||||||
# im Systempfad installiert wurde.
|
|
||||||
CMD ["gunicorn", "main:app", "--bind", "0.0.0.0:80", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker"]
|
CMD ["gunicorn", "main:app", "--bind", "0.0.0.0:80", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker"]
|
||||||
22
main.py
22
main.py
@@ -1,17 +1,24 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
import os
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
# 📁 Dateiname der Datenbank
|
# 📁 Konfiguration: Lese Pfad aus ENV oder nutze Standard
|
||||||
DB_NAME = "hangman.db"
|
# Im Docker Container setzen wir dies später auf /app/data/hangman.db
|
||||||
|
DB_PATH = os.getenv("DB_PATH", "hangman.db")
|
||||||
|
|
||||||
# 🛠️ Datenbank-Hilfsfunktionen
|
# 🛠️ Datenbank-Hilfsfunktionen
|
||||||
def get_db_connection():
|
def get_db_connection():
|
||||||
"""Erstellt eine Verbindung zur SQLite-Datenbank."""
|
"""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
|
conn.row_factory = sqlite3.Row
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
# 💡 Initialisiere die FastAPI-Anwendung (ohne Lifespan/Init-Logik)
|
# 💡 Initialisiere die FastAPI-Anwendung
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
@app.get("/random_word")
|
@app.get("/random_word")
|
||||||
@@ -31,8 +38,7 @@ def get_random_word():
|
|||||||
if result:
|
if result:
|
||||||
return {"word": result["word"]}
|
return {"word": result["word"]}
|
||||||
else:
|
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:
|
except sqlite3.OperationalError as e:
|
||||||
# Fängt den Fall ab, dass die Tabelle noch nicht existiert
|
return {"error": f"Datenbankfehler bei {DB_PATH}: {str(e)}"}
|
||||||
return {"error": "Datenbankfehler: Wurde init.py ausgeführt?"}
|
|
||||||
Reference in New Issue
Block a user