From cf6df4bf2fa07d5fbe837a1143309f2c6b6c4540 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Thu, 10 Nov 2022 17:42:05 +0100 Subject: [PATCH] Switch from uwsgi to gunicorn --- Dockerfile | 31 +++-------------------- docker/run.sh | 4 +++ docker/uwsgi.ini | 15 ----------- poetry.lock | 66 +++++++++++++++++++----------------------------- pyproject.toml | 3 ++- 5 files changed, 36 insertions(+), 83 deletions(-) create mode 100755 docker/run.sh delete mode 100644 docker/uwsgi.ini diff --git a/Dockerfile b/Dockerfile index fe0d6bb..5aa7de3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -93,38 +93,13 @@ ENV PATH /app/venv/bin:$PATH ENV STATIC_ROOT=/app/static COPY --chown=django:django --from=venv $STATIC_ROOT $STATIC_ROOT -# uWSGI env vars -############################################## -ENV UWSGI_HTTP=:8000 -ENV UWSGI_CHDIR="/app/src" -ENV UWSGI_WSGI_FILE="/app/src/charasheet/wsgi.py" - -ENV UWSGI_MASTER=1 -ENV UWSGI_HTTP_AUTO_CHUNKED=1 -ENV UWSGI_HTTP_KEEPALIVE=1 -ENV UWSGI_UID=1000 -ENV UWSGI_GID=1000 -ENV UWSGI_WSGI_ENV_BEHAVIOR=holy -ENV UWSGI_DIE_ON_TERM=true -ENV UWSGI_STRICT=true -ENV UWSGI_NEED_APP=true - -# Tweak for perf -ENV UWSGI_SINGLE_INTERPRETER=true -ENV UWSGI_AUTO_PROCNAME=true -ENV UWSGI_MAX_REQUESTS=5000 -ENV UWSGI_MAX_WORKER_LIFETIME=3600 -ENV UWSGI_RELOAD_ON_RSS=500 -ENV UWSGI_WORKER_RELOAD_MERCY=10 -ENV UWSGI_WORKERS=2 UWSGI_THREADS=4 - # Create directory structure ############################################## WORKDIR /app COPY pyproject.toml poetry.lock ./ ADD --chown=django:django ./src ./src +ADD --chown=django:django ./docker ./docker COPY --chown=django:django tasks.py ./tasks.py -COPY --chown=django:django docker/uwsgi.ini ./uwsgi.ini RUN mkdir -p /app/data /app/db @@ -138,5 +113,7 @@ EXPOSE 8000 WORKDIR /app/src +HEALTHCHECK --start-period=30s CMD python -c "import requests; requests.get('http://localhost:8000', timeout=2)" + USER django -CMD ["uwsgi", "--show-config", "--ini", "/app/uwsgi.ini"] +CMD ["/app/docker/run.sh"] diff --git a/docker/run.sh b/docker/run.sh new file mode 100755 index 0000000..a25776d --- /dev/null +++ b/docker/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -eux +python manage.py migrate --noinput +gunicorn blog.wsgi -b 0.0.0.0:8000 --log-file - diff --git a/docker/uwsgi.ini b/docker/uwsgi.ini deleted file mode 100644 index a841ae5..0000000 --- a/docker/uwsgi.ini +++ /dev/null @@ -1,15 +0,0 @@ -[uwsgi] -plugin = /app/escape_json_plugin.so - -static-map = /media=/app/data/media/ -logger-req = stdio -; json_uri and json_host are json-escaped fields defined in `escape_json_plugin.so` -log-format = "address":"%(addr)", "host":"%(json_host)", "method":"%(method)", "uri":"%(json_uri)", "protocol":"%(proto)", "resp_size":%(size), "req_body_size":%(cl), "resp_status":%(status), "resp_time":%(msecs), "referer":"%(referer)", "user_agent":"%(uagent)" -log-req-encoder = format {"source":"uwsgi-req", "time":"${strftime:%%FT%%T%%z}", ${msg}} -log-req-encoder = nl - -; Ignore write errors -; https://github.com/getsentry/raven-python/issues/732#issuecomment-176854438 -ignore-sigpipe = true -ignore-write-errors = true -disable-write-exception = true diff --git a/poetry.lock b/poetry.lock index 5a32246..4ce40f6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -37,7 +37,7 @@ python-versions = ">=3.5" dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] -tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] name = "beautifulsoup4" @@ -125,7 +125,7 @@ optional = false python-versions = ">=3.6.0" [package.extras] -unicode-backport = ["unicodedata2"] +unicode_backport = ["unicodedata2"] [[package]] name = "colorama" @@ -218,7 +218,7 @@ django = ">=2.0" requests = ">=2.4.3" [package.extras] -amazon-ses = ["boto3"] +amazon_ses = ["boto3"] dev = ["flake8", "sphinx", "sphinx-rtd-theme", "tox", "twine", "wheel"] postal = ["cryptography"] @@ -365,7 +365,21 @@ optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" [package.extras] -docs = ["Sphinx"] +docs = ["sphinx"] + +[[package]] +name = "gunicorn" +version = "20.1.0" +description = "WSGI HTTP Server for UNIX" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.extras] +eventlet = ["eventlet (>=0.24.1)"] +gevent = ["gevent (>=1.4.0)"] +setproctitle = ["setproctitle"] +tornado = ["tornado (>=0.2)"] [[package]] name = "h11" @@ -480,9 +494,6 @@ category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" -[package.dependencies] -setuptools = "*" - [[package]] name = "outcome" version = "1.2.0" @@ -689,7 +700,7 @@ pytest = ">=5.4.0" [package.extras] docs = ["sphinx", "sphinx-rtd-theme"] -testing = ["Django", "django-configurations (>=2.0)"] +testing = ["django", "django-configurations (>=2.0)"] [[package]] name = "pytest-html" @@ -774,7 +785,7 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-toolbelt" @@ -801,19 +812,6 @@ trio = ">=0.17,<1.0" trio-websocket = ">=0.9,<1.0" urllib3 = {version = ">=1.26,<2.0", extras = ["socks"]} -[[package]] -name = "setuptools" -version = "65.5.1" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - [[package]] name = "six" version = "1.16.0" @@ -925,14 +923,6 @@ brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -[[package]] -name = "uwsgi" -version = "2.0.21" -description = "The uWSGI server" -category = "main" -optional = false -python-versions = "*" - [[package]] name = "virtualenv" version = "20.16.6" @@ -967,7 +957,7 @@ optional = false python-versions = ">=3.7" [package.extras] -brotli = ["Brotli"] +brotli = ["brotli"] [[package]] name = "wsproto" @@ -983,7 +973,7 @@ h11 = ">=0.9.0,<1" [metadata] lock-version = "1.1" python-versions = ">=3.10.0, <4" -content-hash = "cd49a04260ba22d4bbe1ba66bf7ed229d16b22c91d6ab7d25e24fe73ac307be9" +content-hash = "a8492fca0c4d83c2605cfd4e6aa9f043ba5969bd497ab20876ee1f93f2520d1f" [metadata.files] ansicon = [ @@ -1321,6 +1311,10 @@ greenlet = [ {file = "greenlet-1.1.3.post0-cp39-cp39-win_amd64.whl", hash = "sha256:91a84faf718e6f8b888ca63d0b2d6d185c8e2a198d2a7322d75c303e7097c8b7"}, {file = "greenlet-1.1.3.post0.tar.gz", hash = "sha256:f5e09dc5c6e1796969fd4b775ea1417d70e49a5df29aaa8e5d10675d9e11872c"}, ] +gunicorn = [ + {file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"}, + {file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"}, +] h11 = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -1387,7 +1381,6 @@ pre-commit = [ ] prettytable = [ {file = "prettytable-3.5.0-py3-none-any.whl", hash = "sha256:fe391c3b545800028edf5dbb6a5360893feb398367fcc1cf8d7a5b29ce5c59a1"}, - {file = "prettytable-3.5.0.tar.gz", hash = "sha256:52f682ba4efe29dccb38ff0fe5bac8a23007d0780ff92a8b85af64bc4fc74d72"}, ] psycopg2-binary = [ {file = "psycopg2-binary-2.9.5.tar.gz", hash = "sha256:33e632d0885b95a8b97165899006c40e9ecdc634a529dca7b991eb7de4ece41c"}, @@ -1570,10 +1563,6 @@ requests-toolbelt = [ selenium = [ {file = "selenium-4.5.0-py3-none-any.whl", hash = "sha256:a733dd77d3171b846893f4d51b18967d809313f547a10974e26579f9ce797462"}, ] -setuptools = [ - {file = "setuptools-65.5.1-py3-none-any.whl", hash = "sha256:d0b9a8433464d5800cbe05094acf5c6d52a91bfac9b52bcfc4d41382be5d5d31"}, - {file = "setuptools-65.5.1.tar.gz", hash = "sha256:e197a19aa8ec9722928f2206f8de752def0e4c9fc6953527360d1c36d94ddb2f"}, -] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -1618,9 +1607,6 @@ urllib3 = [ {file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"}, {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, ] -uwsgi = [ - {file = "uwsgi-2.0.21.tar.gz", hash = "sha256:35a30d83791329429bc04fe44183ce4ab512fcf6968070a7bfba42fc5a0552a9"}, -] virtualenv = [ {file = "virtualenv-20.16.6-py3-none-any.whl", hash = "sha256:186ca84254abcbde98180fd17092f9628c5fe742273c02724972a1d8a2035108"}, {file = "virtualenv-20.16.6.tar.gz", hash = "sha256:530b850b523c6449406dfba859d6345e48ef19b8439606c5d74d7d3c9e14d76e"}, diff --git a/pyproject.toml b/pyproject.toml index b7c1eae..d1c6080 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,12 +17,13 @@ django-linear-migrations = ">=2.2.0" django-extensions = ">=3.1.5" psycopg2-binary = ">=2.8" whitenoise = ">=6.2" -uWSGI = ">=2.0.21" selenium = ">=4.5.0" Markdown = ">=3.2" django-registration = ">=3.3" django-anymail = {extras = ["mailgun"], version = ">=8.6"} django-bootstrap5 = ">=22.1" +requests = ">=2.28.1" +gunicorn = "^20.1.0" [tool.poetry.dev-dependencies] django-debug-toolbar = ">=3.2"