commit 47bbb5fcb47883ed7a19dd7436ffd947637f553e Author: Kosmos Date: Mon Aug 24 22:29:37 2026 +0000 Initial Docker deployment setup 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..4f472d8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# 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 ./ + +# Compile the binaries from the backend source code. Cache the build data. +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..bb2174a --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +# Drivers Hub: Docker Deployment + +```text + ____ _ __ __ __ + / __ \_____(_) _____ __________ / / / /_ __/ /_ + / / / / ___/ / | / / _ \/ ___/ ___/ / /_/ / / / / __ \ + / /_/ / / / /| |/ / __/ / (__ ) / __ / /_/ / /_/ / +/_____/_/ /_/ |___/\___/_/ /____/ /_/ /_/\__,_/_.___/ +``` + +Docker deployment for [Drivers Hub: Backend](https://github.com/CharlesWithC/HubBackend). +The deployment includes MariaDB, Valkey, and the banner generator. + +## Configure the deployment + +Get the backend source code. Then, create the deployment configuration and the +application configuration: + +```bash +git clone https://github.com/CharlesWithC/HubBackend.git upstream/HubBackend +cp .env.example .env +cp upstream/HubBackend/config_sample.json config/config.json +``` + +Set secure MariaDB passwords in `.env`. Then, set at least these values in +`config/config.json`: + +```json +{ + "abbr": "drivershub", + "name": "Drivers Hub", + "domain": "hub.example.com", + "prefix": "/api", + "server_host": "0.0.0.0", + "server_port": 7777, + "db_host": "mariadb", + "db_user": "drivershub", + "db_password": "use the DB_PASSWORD value from .env", + "db_name": "drivershub", + "db_data_directory": "/var/lib/mysqlext/", + "redis_host": "valkey", + "redis_port": 6379 +} +``` + +The example shows only the values that you must change. Keep all other values +from `config_sample.json`. Restart the backend after you change +`config/config.json`. + +Use the same database password in `.env` and `config/config.json`. +Set `domain` to the public host name of the backend. Do not include a protocol or +path. + +## Start the deployment + +```bash +docker compose build +docker compose up -d +docker compose ps +``` + +By default, the API is available at `http://localhost:7777/api`. Swagger UI is +available at `http://localhost:7777/api/doc`. + +## Store persistent data + +The deployment stores all persistent data in these directories: + +```text +data/ +├── mariadb/ +├── mariadb-external/ +└── valkey/ +``` + +Docker creates these directories at the first start. MariaDB and Valkey do not +publish ports on the host. + +The `docker compose down` command removes the containers and the network. It does +not remove `config/` or `data/`. Back up these directories separately. + +## Update the backend + +Update the backend source code. Then, rebuild the containers: + +```bash +git -C upstream/HubBackend pull --ff-only +docker compose build +docker compose up -d +``` + +## Operate the deployment + +```bash +# Show the backend logs. +docker compose logs -f backend + +# Restart the backend after a configuration change. +docker compose restart backend + +# Create a user. +docker compose run --rm backend \ + drivershub --config /app/config/config.json setup create-user user@example.com +``` + +## Attribution + +[Drivers Hub: Backend](https://github.com/CharlesWithC/HubBackend) is developed +by [CharlesWithC](https://charlws.com) and is licensed under the GNU Affero +General Public License v3.0. This repository provides an independent Docker +deployment for that project. diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..767e415 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,70 @@ +# Use the backend source code 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..e06cbe7 --- /dev/null +++ b/config/.gitignore @@ -0,0 +1,4 @@ +# Ignore the local application configuration. +config.json +*.saved +!.gitignore diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 0000000..6de2c21 --- /dev/null +++ b/data/.gitignore @@ -0,0 +1,3 @@ +# Ignore database and cache files. +* +!.gitignore diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100755 index 0000000..3bba72b --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Start a compiled program. +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..cb125ca --- /dev/null +++ b/docker/mariadb-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# Prepare the external table directory. Then, start MariaDB. +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..a0defe0 --- /dev/null +++ b/docker/mariadb-init.sql @@ -0,0 +1,3 @@ +-- The DATA DIRECTORY table definitions require this privilege. +GRANT FILE ON *.* TO 'drivershub'@'%'; +FLUSH PRIVILEGES;