From 9faaee714a2ecd037527d71f37611b8bf58658ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn-Michael=20Miehe?= <40151420+ldericher@users.noreply.github.com> Date: Wed, 15 Nov 2023 09:26:18 +0100 Subject: [PATCH] add "mini-tiangolo" to Dockerfile - tiangolo/uvicorn-gunicorn is not available for ARM arch --- Dockerfile | 28 ++++++++--- install/mini-tiangolo/gunicorn_conf.py | 67 ++++++++++++++++++++++++++ install/mini-tiangolo/start.sh | 20 ++++++++ 3 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 install/mini-tiangolo/gunicorn_conf.py create mode 100644 install/mini-tiangolo/start.sh diff --git a/Dockerfile b/Dockerfile index f708a7b..1dac049 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,12 +17,31 @@ RUN yarn install --production false COPY ui ./ RUN yarn build --dest /tmp/ovdashboard_ui/html +###################### +# python preparation # +###################### + +ARG PYTHON_VERSION +FROM python:${PYTHON_VERSION} as uvicorn-gunicorn + +# where credit is due ... +LABEL maintainer="Sebastian Ramirez " +WORKDIR /usr/local/share/uvicorn-gunicorn + +# install uvicorn-gunicorn +COPY "./install/mini-tiangolo/" "." + +RUN set -ex; \ + chmod +x start.sh; \ + python3 -m pip --no-cache-dir install gunicorn; + +CMD ["/usr/local/share/uvicorn-gunicorn/start.sh"] + ########### # web app # ########### -ARG PYTHON_VERSION -FROM tiangolo/uvicorn-gunicorn:python${PYTHON_VERSION} AS production +FROM uvicorn-gunicorn AS production # env setup WORKDIR /usr/local/src/ovdashboard_api @@ -40,11 +59,8 @@ RUN set -ex; \ libmagic1 \ ; rm -rf /var/lib/apt/lists/*; \ \ - # remove example app - rm -rf /app; \ - \ # install ovdashboard_api - python -m pip --no-cache-dir install ./ + python3 -m pip --no-cache-dir install ./ # add prepared ovdashboard_ui COPY --from=build-ui /tmp/ovdashboard_ui /usr/local/share/ovdashboard_ui diff --git a/install/mini-tiangolo/gunicorn_conf.py b/install/mini-tiangolo/gunicorn_conf.py new file mode 100644 index 0000000..7dd141d --- /dev/null +++ b/install/mini-tiangolo/gunicorn_conf.py @@ -0,0 +1,67 @@ +import json +import multiprocessing +import os + +workers_per_core_str = os.getenv("WORKERS_PER_CORE", "1") +max_workers_str = os.getenv("MAX_WORKERS") +use_max_workers = None +if max_workers_str: + use_max_workers = int(max_workers_str) +web_concurrency_str = os.getenv("WEB_CONCURRENCY", None) + +host = os.getenv("HOST", "0.0.0.0") +port = os.getenv("PORT", "80") +bind_env = os.getenv("BIND", None) +use_loglevel = os.getenv("LOG_LEVEL", "info") +if bind_env: + use_bind = bind_env +else: + use_bind = f"{host}:{port}" + +cores = multiprocessing.cpu_count() +workers_per_core = float(workers_per_core_str) +default_web_concurrency = workers_per_core * cores +if web_concurrency_str: + web_concurrency = int(web_concurrency_str) + assert web_concurrency > 0 +else: + web_concurrency = max(int(default_web_concurrency), 2) + if use_max_workers: + web_concurrency = min(web_concurrency, use_max_workers) +accesslog_var = os.getenv("ACCESS_LOG", "-") +use_accesslog = accesslog_var or None +errorlog_var = os.getenv("ERROR_LOG", "-") +use_errorlog = errorlog_var or None +graceful_timeout_str = os.getenv("GRACEFUL_TIMEOUT", "120") +timeout_str = os.getenv("TIMEOUT", "120") +keepalive_str = os.getenv("KEEP_ALIVE", "5") + +# Gunicorn config variables +loglevel = use_loglevel +workers = web_concurrency +bind = use_bind +errorlog = use_errorlog +worker_tmp_dir = "/dev/shm" +accesslog = use_accesslog +graceful_timeout = int(graceful_timeout_str) +timeout = int(timeout_str) +keepalive = int(keepalive_str) + + +# For debugging and testing +log_data = { + "loglevel": loglevel, + "workers": workers, + "bind": bind, + "graceful_timeout": graceful_timeout, + "timeout": timeout, + "keepalive": keepalive, + "errorlog": errorlog, + "accesslog": accesslog, + # Additional, non-gunicorn variables + "workers_per_core": workers_per_core, + "use_max_workers": use_max_workers, + "host": host, + "port": port, +} +print(json.dumps(log_data)) diff --git a/install/mini-tiangolo/start.sh b/install/mini-tiangolo/start.sh new file mode 100644 index 0000000..b72737b --- /dev/null +++ b/install/mini-tiangolo/start.sh @@ -0,0 +1,20 @@ +#!/bin/sh +set -e + +MODULE_NAME=${MODULE_NAME:-"app.main"} +VARIABLE_NAME=${VARIABLE_NAME:-"app"} +export APP_MODULE="${APP_MODULE:-"$MODULE_NAME:$VARIABLE_NAME"}" +export GUNICORN_CONF="${GUNICORN_CONF:-"/usr/local/share/uvicorn-gunicorn/gunicorn_conf.py"}" +export WORKER_CLASS="${WORKER_CLASS:-"uvicorn.workers.UvicornWorker"}" + +if [ -f "${PRE_START_PATH}" ] ; then + echo "Running script ${PRE_START_PATH}" + # shellcheck disable=SC1090 + . "${PRE_START_PATH}" +fi + +# Start Gunicorn +exec gunicorn \ + -k "${WORKER_CLASS}" \ + -c "${GUNICORN_CONF}" \ + "${APP_MODULE}"