diff --git a/Dockerfile b/Dockerfile index 7765628..8cfa199 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,5 +49,5 @@ USER nobody # Expose port EXPOSE 8000 -# Use environment variable for workers count and optimize for database connections -CMD ["sh", "-c", "gunicorn app.main:app -k uvicorn.workers.UvicornWorker --workers ${WORKERS:-5} --bind 0.0.0.0:8000 --timeout 120 --max-requests 1000 --max-requests-jitter 100"] +# Use Gunicorn config so worker lifecycle settings are explicit and env-overridable. +CMD ["gunicorn", "app.main:app", "--config", "gunicorn_conf.py"] diff --git a/gunicorn_conf.py b/gunicorn_conf.py new file mode 100644 index 0000000..239a136 --- /dev/null +++ b/gunicorn_conf.py @@ -0,0 +1,21 @@ +import os + + +def _int_env(name: str, default: int) -> int: + value = os.getenv(name) + if value is None or value == "": + return default + return int(value) + + +bind = f"0.0.0.0:{os.getenv('PORT', '8000')}" +worker_class = "uvicorn.workers.UvicornWorker" +workers = _int_env("WORKERS", 5) + +# Long provider streams should not be interrupted by the default 30s graceful +# shutdown window, and workers should not recycle while streaming requests run. +timeout = _int_env("GUNICORN_TIMEOUT", 300) +graceful_timeout = _int_env("GUNICORN_GRACEFUL_TIMEOUT", 300) +keepalive = _int_env("GUNICORN_KEEPALIVE", 75) +max_requests = _int_env("GUNICORN_MAX_REQUESTS", 0) +max_requests_jitter = _int_env("GUNICORN_MAX_REQUESTS_JITTER", 0)