From 94d729ec1a0f52f25f9d6870f90f7c2d9c08b5d0 Mon Sep 17 00:00:00 2001 From: Kosmos Date: Mon, 24 Aug 2026 22:29:37 +0000 Subject: [PATCH] Initial Docker deployment setup --- .dockerignore | 10 +++ .env.example | 6 ++ .gitignore | 5 ++ Dockerfile | 46 ++++++++++++++ README.md | 115 +++++++++++++++++++++++++++++++++++ compose.yaml | 70 +++++++++++++++++++++ config/.gitignore | 4 ++ data/.gitignore | 3 + docker/entrypoint.sh | 15 +++++ docker/mariadb-entrypoint.sh | 8 +++ docker/mariadb-init.sql | 3 + 11 files changed, 285 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 compose.yaml create mode 100644 config/.gitignore create mode 100644 data/.gitignore create mode 100755 docker/entrypoint.sh create mode 100755 docker/mariadb-entrypoint.sh create mode 100644 docker/mariadb-init.sql diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..19409d0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +upstream/HubBackend/.git +.venv* +build +dist +releases +data +config/config.json +__pycache__ +*.py[cod] +.env diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..482fa6d --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +# Host port of the Drivers Hub API. +HUB_PORT=7777 + +DB_NAME=drivershub +DB_PASSWORD=replace-with-a-long-random-password +DB_ROOT_PASSWORD=replace-with-another-long-random-password diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..77e8131 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.env +config/config.json +data/* +!data/.gitignore +upstream/HubBackend/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e25e3d0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +# syntax=docker/dockerfile:1 + +FROM python:3.12-trixie AS builder + +WORKDIR /build + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ccache \ + gcc \ + g++ \ + libmariadb-dev \ + make \ + patchelf \ + python3-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY upstream/HubBackend/requirements.txt upstream/HubBackend/makefile ./ +COPY upstream/HubBackend/src ./src +COPY upstream/HubBackend/config_sample.json upstream/HubBackend/openapi.json ./ + +# The binaries are compiled from this checkout. BuildKit's cache keeps repeated +# Nuitka builds reasonably fast without putting build tools in the final image. +RUN --mount=type=cache,target=/root/.cache/pip \ + --mount=type=cache,target=/root/.cache/ccache \ + make install-python \ + && make -j"$(nproc)" build + +FROM debian:trixie-slim AS runtime + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates \ + && rm -rf /var/lib/apt/lists/* \ + && groupadd --system --gid 10001 drivershub \ + && useradd --system --uid 10001 --gid drivershub --home-dir /app drivershub + +WORKDIR /app + +COPY --from=builder --chown=drivershub:drivershub /build/dist/ ./ +COPY --chown=root:root docker/entrypoint.sh /usr/local/bin/drivershub-entrypoint + +USER drivershub +EXPOSE 7777 8700 + +ENTRYPOINT ["drivershub-entrypoint"] +CMD ["drivershub", "--config", "/app/config/config.json", "--banner-service-url", "http://bannergen:8700/banner"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..962e028 --- /dev/null +++ b/README.md @@ -0,0 +1,115 @@ +# Docker-Deployment + +Dieses Compose-Rezept baut sowohl das Backend als auch den Banner-Generator mit +Nuitka direkt aus dem aktuellen Checkout. Es wird kein vorcompiliertes +Drivers-Hub-Binary heruntergeladen. Das fertige Runtime-Image enthält weder den +Compiler noch eine Python-Laufzeitumgebung. + +Der Stack umfasst Drivers Hub, Banner-Generator, MariaDB 10.11 und Valkey 8. Die +Datenbank wird vor dem ersten Backend-Start durch den einmaligen Dienst `db-init` +initialisiert. + +## Konfiguration + +Zuerst werden die Deployment- und Anwendungskonfiguration angelegt: + +```bash +cp .env.example .env +cp upstream/HubBackend/config_sample.json config/config.json +``` + +In `.env` müssen sichere Passwörter für MariaDB eingetragen werden. Anschließend +wird `config/config.json` mindestens wie folgt angepasst: + +```json +{ + "abbr": "drivershub", + "name": "Drivers Hub", + "domain": "localhost", + "prefix": "/api", + "server_host": "0.0.0.0", + "server_port": 7777, + "db_host": "mariadb", + "db_user": "drivershub", + "db_password": "dasselbe Passwort wie DB_PASSWORD in .env", + "db_name": "drivershub", + "db_data_directory": "/var/lib/mysqlext/", + "redis_host": "valkey", + "redis_port": 6379 +} +``` + +Die gezeigten Schlüssel sind nur die zu ändernden Werte. Alle übrigen Schlüssel +aus `config_sample.json` müssen erhalten bleiben. `config/config.json` ist die +echte, persistente Anwendungskonfiguration und kann im laufenden Betrieb weiter +bearbeitet werden. Ein Image-Neubau ist für Konfigurationsänderungen nicht nötig; +anschließend genügt ein Neustart des Backends. + +Das Datenbankpasswort muss in `.env` und `config/config.json` übereinstimmen, da +sowohl der MariaDB-Container als auch Drivers Hub es unabhängig voneinander beim +Start benötigen. Alle rein fachlichen Einstellungen werden ausschließlich in +`config/config.json` gepflegt. + +## Start + +```bash +docker compose build +docker compose up -d +docker compose ps +``` + +Standardmäßig ist die API unter `http://localhost:7777/api` und Swagger UI unter +`http://localhost:7777/api/doc` erreichbar. + +## Persistente Daten + +Alle persistenten Daten liegen im Projektverzeichnis: + +```text +data/ +├── mariadb/ +├── mariadb-external/ +└── valkey/ +``` + +Die Verzeichnisse entstehen beim ersten Start automatisch. Alternativ können die +drei Host-Pfade in `compose.yaml` beispielsweise nach `../drivershub-data/` +geändert werden. MariaDB und Valkey veröffentlichen keine Ports am Host. + +`docker compose down` entfernt Container und Netzwerk, lässt `config/` und +`data/` aber unangetastet. Diese Verzeichnisse müssen bewusst separat gesichert +oder gelöscht werden. + +## Upstream aktualisieren + +`upstream/HubBackend` ist ein normaler, eigenständiger Git-Clone und bleibt +inhaltlich unverändert. Ein Update und anschließender Neubau erfolgen mit: + +```bash +git -C upstream/HubBackend pull --ff-only +docker compose build +docker compose up -d +``` + +## Betrieb + +```bash +# Logs anzeigen +docker compose logs -f backend + +# Nach Änderungen an config/config.json +docker compose restart backend + +# Benutzer mit dem compilierten Programm anlegen +docker compose run --rm backend \ + drivershub --config /app/config/config.json setup create-user user@example.com + +# Nach Änderungen am Quellcode neu bauen +docker compose build +docker compose up -d +``` + +MariaDB erhält für den festen Benutzer `drivershub` das globale `FILE`-Recht, +weil das Projekt Tabellen mit `DATA DIRECTORY` anlegt. Eine Änderung dieses +Benutzernamens muss sowohl in `compose.yaml`, `config/config.json` als auch in +`docker/mariadb-init.sql` nachvollzogen werden. diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..0f07b76 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,70 @@ +# Deployment stack for the unmodified source checkout in upstream/HubBackend. +name: drivershub + +services: + mariadb: + image: mariadb:10.11 + restart: unless-stopped + entrypoint: ["/usr/local/bin/hub-mariadb-entrypoint"] + command: ["mariadbd"] + environment: + MARIADB_DATABASE: ${DB_NAME:-drivershub} + MARIADB_USER: drivershub + MARIADB_PASSWORD: ${DB_PASSWORD:-change-me} + MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-change-root-me} + volumes: + - ./data/mariadb:/var/lib/mysql + - ./data/mariadb-external:/var/lib/mysqlext + - ./docker/mariadb-entrypoint.sh:/usr/local/bin/hub-mariadb-entrypoint:ro + - ./docker/mariadb-init.sql:/docker-entrypoint-initdb.d/10-drivershub.sql:ro + healthcheck: + test: ["CMD-SHELL", "healthcheck.sh --connect --innodb_initialized"] + interval: 5s + timeout: 5s + retries: 30 + + valkey: + image: valkey/valkey:8-alpine + restart: unless-stopped + command: ["valkey-server", "--appendonly", "yes"] + volumes: + - ./data/valkey:/data + healthcheck: + test: ["CMD", "valkey-cli", "ping"] + interval: 5s + timeout: 3s + retries: 20 + + db-init: + build: + context: . + command: ["drivershub", "--config", "/app/config/config.json", "setup", "init-db"] + volumes: + - ./config:/app/config + depends_on: + mariadb: + condition: service_healthy + restart: "no" + + bannergen: + build: + context: . + restart: unless-stopped + command: ["bannergen", "--host", "0.0.0.0", "--port", "8700", "--workers", "2"] + + backend: + build: + context: . + restart: unless-stopped + command: ["drivershub", "--config", "/app/config/config.json", "--banner-service-url", "http://bannergen:8700/banner"] + volumes: + - ./config:/app/config + ports: + - "${HUB_PORT:-7777}:7777" + depends_on: + db-init: + condition: service_completed_successfully + valkey: + condition: service_healthy + bannergen: + condition: service_started diff --git a/config/.gitignore b/config/.gitignore new file mode 100644 index 0000000..ed5fbf3 --- /dev/null +++ b/config/.gitignore @@ -0,0 +1,4 @@ +# Local application configuration. +config.json +*.saved +!.gitignore diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 0000000..17dd2c5 --- /dev/null +++ b/data/.gitignore @@ -0,0 +1,3 @@ +# Runtime database and cache files. +* +!.gitignore diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100755 index 0000000..f3e06df --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Runtime launcher for the compiled programs. +set -eu + +if [ "${1:-}" = "drivershub" ]; then + shift + exec /app/drivershub "$@" +fi + +if [ "${1:-}" = "bannergen" ]; then + shift + exec /app/bannergen "$@" +fi + +exec "$@" diff --git a/docker/mariadb-entrypoint.sh b/docker/mariadb-entrypoint.sh new file mode 100755 index 0000000..3ce314f --- /dev/null +++ b/docker/mariadb-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# Prepare the bind-mounted external table directory before MariaDB starts. +set -eu + +mkdir -p /var/lib/mysqlext +chown mysql:mysql /var/lib/mysqlext + +exec /usr/local/bin/docker-entrypoint.sh "$@" diff --git a/docker/mariadb-init.sql b/docker/mariadb-init.sql new file mode 100644 index 0000000..178b67e --- /dev/null +++ b/docker/mariadb-init.sql @@ -0,0 +1,3 @@ +-- Required by the upstream schema's DATA DIRECTORY table definitions. +GRANT FILE ON *.* TO 'drivershub'@'%'; +FLUSH PRIVILEGES;