bump version to 24.0.0, remove sphinx docs
160
docs/Makefile
@ -1,160 +0,0 @@
|
|||||||
# Makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
# if you want to compare this file to current sphinx defaults, recreate it:
|
|
||||||
# BUILDDIR=build sphinx-quickstart --sep --extensions=gunicorn_ext --templatedir=_templates --makefile --batchfile --no-use-make-mode --master=index
|
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
|
||||||
PYTHON = python
|
|
||||||
SPHINXOPTS =
|
|
||||||
SPHINXBUILD = sphinx-build
|
|
||||||
PAPER =
|
|
||||||
BUILDDIR = build
|
|
||||||
|
|
||||||
# Internal variables.
|
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
|
||||||
PAPEROPT_letter = -D latex_paper_size=letter
|
|
||||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
|
||||||
# the i18n builder cannot share the environment and doctrees with the others
|
|
||||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
|
||||||
|
|
||||||
.PHONY: help clean html htmlview dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
|
||||||
|
|
||||||
help:
|
|
||||||
@echo "Please use \`make <target>' where <target> is one of"
|
|
||||||
@echo " html to make standalone HTML files"
|
|
||||||
@echo " htmlview to open the index page built by the html target in your browser"
|
|
||||||
@echo " dirhtml to make HTML files named index.html in directories"
|
|
||||||
@echo " singlehtml to make a single large HTML file"
|
|
||||||
@echo " pickle to make pickle files"
|
|
||||||
@echo " json to make JSON files"
|
|
||||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
|
||||||
@echo " qthelp to make HTML files and a qthelp project"
|
|
||||||
@echo " devhelp to make HTML files and a Devhelp project"
|
|
||||||
@echo " epub to make an epub"
|
|
||||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
|
||||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
|
||||||
@echo " text to make text files"
|
|
||||||
@echo " man to make manual pages"
|
|
||||||
@echo " texinfo to make Texinfo files"
|
|
||||||
@echo " info to make Texinfo files and run them through makeinfo"
|
|
||||||
@echo " gettext to make PO message catalogs"
|
|
||||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
|
||||||
@echo " linkcheck to check all external links for integrity"
|
|
||||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm -rf $(BUILDDIR)/*
|
|
||||||
|
|
||||||
html:
|
|
||||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
|
||||||
|
|
||||||
htmlview: html
|
|
||||||
$(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')"
|
|
||||||
|
|
||||||
dirhtml:
|
|
||||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
|
||||||
|
|
||||||
singlehtml:
|
|
||||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
|
||||||
|
|
||||||
pickle:
|
|
||||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the pickle files."
|
|
||||||
|
|
||||||
json:
|
|
||||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the JSON files."
|
|
||||||
|
|
||||||
htmlhelp:
|
|
||||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
|
||||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
|
||||||
|
|
||||||
qthelp:
|
|
||||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
|
||||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
|
||||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Gunicorn.qhcp"
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Gunicorn.qhc"
|
|
||||||
|
|
||||||
devhelp:
|
|
||||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished."
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Gunicorn"
|
|
||||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Gunicorn"
|
|
||||||
@echo "# devhelp"
|
|
||||||
|
|
||||||
epub:
|
|
||||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
|
||||||
|
|
||||||
latex:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
|
||||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
|
||||||
"(use \`make latexpdf' here to do that automatically)."
|
|
||||||
|
|
||||||
latexpdf:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through pdflatex..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
text:
|
|
||||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
|
||||||
|
|
||||||
man:
|
|
||||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
|
||||||
|
|
||||||
texinfo:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
|
||||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
|
||||||
"(use \`make info' here to do that automatically)."
|
|
||||||
|
|
||||||
info:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo "Running Texinfo files through makeinfo..."
|
|
||||||
make -C $(BUILDDIR)/texinfo info
|
|
||||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
|
||||||
|
|
||||||
gettext:
|
|
||||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
|
||||||
|
|
||||||
changes:
|
|
||||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
|
||||||
@echo
|
|
||||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
|
||||||
|
|
||||||
linkcheck:
|
|
||||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
|
||||||
@echo
|
|
||||||
@echo "Link check complete; look for any errors in the above output " \
|
|
||||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
|
||||||
|
|
||||||
doctest:
|
|
||||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
|
||||||
@echo "Testing of doctests in the sources finished, look at the " \
|
|
||||||
"results in $(BUILDDIR)/doctest/output.txt."
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
Generate Documentation
|
|
||||||
======================
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
------------
|
|
||||||
|
|
||||||
To generate documentation you need to install:
|
|
||||||
|
|
||||||
- Python >= 3.7
|
|
||||||
- Sphinx (https://www.sphinx-doc.org/)
|
|
||||||
|
|
||||||
|
|
||||||
Generate html
|
|
||||||
-------------
|
|
||||||
::
|
|
||||||
|
|
||||||
$ make html
|
|
||||||
|
|
||||||
The command generates html document inside ``build/html`` dir.
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
import os
|
|
||||||
import inspect
|
|
||||||
|
|
||||||
from docutils import nodes, utils
|
|
||||||
|
|
||||||
import gunicorn.config as guncfg
|
|
||||||
|
|
||||||
HEAD = """\
|
|
||||||
.. Please update gunicorn/config.py instead.
|
|
||||||
|
|
||||||
.. _settings:
|
|
||||||
|
|
||||||
Settings
|
|
||||||
========
|
|
||||||
|
|
||||||
This is an exhaustive list of settings for Gunicorn. Some settings are only
|
|
||||||
able to be set from a configuration file. The setting name is what should be
|
|
||||||
used in the configuration file. The command line arguments are listed as well
|
|
||||||
for reference on setting at the command line.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Settings can be specified by using environment variable
|
|
||||||
``GUNICORN_CMD_ARGS``. All available command line arguments can be used.
|
|
||||||
For example, to specify the bind address and number of workers::
|
|
||||||
|
|
||||||
$ GUNICORN_CMD_ARGS="--bind=127.0.0.1 --workers=3" gunicorn app:app
|
|
||||||
|
|
||||||
.. versionadded:: 19.7
|
|
||||||
|
|
||||||
"""
|
|
||||||
ISSUE_URI = 'https://github.com/benoitc/gunicorn/issues/%s'
|
|
||||||
PULL_REQUEST_URI = 'https://github.com/benoitc/gunicorn/pull/%s'
|
|
||||||
|
|
||||||
|
|
||||||
def format_settings(app):
|
|
||||||
settings_file = os.path.join(app.srcdir, "settings.rst")
|
|
||||||
ret = []
|
|
||||||
known_settings = sorted(guncfg.KNOWN_SETTINGS, key=lambda s: s.section)
|
|
||||||
for i, s in enumerate(known_settings):
|
|
||||||
if i == 0 or s.section != known_settings[i - 1].section:
|
|
||||||
ret.append("%s\n%s\n\n" % (s.section, "-" * len(s.section)))
|
|
||||||
ret.append(fmt_setting(s))
|
|
||||||
|
|
||||||
with open(settings_file, 'w') as settings:
|
|
||||||
settings.write(HEAD)
|
|
||||||
settings.write(''.join(ret))
|
|
||||||
|
|
||||||
|
|
||||||
def fmt_setting(s):
|
|
||||||
if hasattr(s, "default_doc"):
|
|
||||||
val = s.default_doc
|
|
||||||
elif callable(s.default):
|
|
||||||
val = inspect.getsource(s.default)
|
|
||||||
val = "\n".join(" %s" % line for line in val.splitlines())
|
|
||||||
val = "\n\n.. code-block:: python\n\n" + val
|
|
||||||
elif s.default == '':
|
|
||||||
val = "``''``"
|
|
||||||
else:
|
|
||||||
val = "``%r``" % s.default
|
|
||||||
|
|
||||||
if s.cli and s.meta:
|
|
||||||
cli = " or ".join("``%s %s``" % (arg, s.meta) for arg in s.cli)
|
|
||||||
elif s.cli:
|
|
||||||
cli = " or ".join("``%s``" % arg for arg in s.cli)
|
|
||||||
else:
|
|
||||||
cli = ""
|
|
||||||
|
|
||||||
out = []
|
|
||||||
out.append(".. _%s:\n" % s.name.replace("_", "-"))
|
|
||||||
out.append("``%s``" % s.name)
|
|
||||||
out.append("~" * (len(s.name) + 4))
|
|
||||||
out.append("")
|
|
||||||
if s.cli:
|
|
||||||
out.append("**Command line:** %s" % cli)
|
|
||||||
out.append("")
|
|
||||||
out.append("**Default:** %s" % val)
|
|
||||||
out.append("")
|
|
||||||
out.append(s.desc)
|
|
||||||
out.append("")
|
|
||||||
out.append("")
|
|
||||||
return "\n".join(out)
|
|
||||||
|
|
||||||
|
|
||||||
def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
||||||
issue = utils.unescape(text)
|
|
||||||
text = 'issue ' + issue
|
|
||||||
refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue)
|
|
||||||
return [refnode], []
|
|
||||||
|
|
||||||
|
|
||||||
def pull_request_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
||||||
issue = utils.unescape(text)
|
|
||||||
text = 'pull request ' + issue
|
|
||||||
refnode = nodes.reference(text, text, refuri=PULL_REQUEST_URI % issue)
|
|
||||||
return [refnode], []
|
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
|
||||||
app.connect('builder-inited', format_settings)
|
|
||||||
app.add_role('issue', issue_role)
|
|
||||||
app.add_role('pr', pull_request_role)
|
|
||||||
|
Before Width: | Height: | Size: 21 KiB |
@ -1,119 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
version="1.1"
|
|
||||||
width="740.18402"
|
|
||||||
height="161.62476"
|
|
||||||
id="svg4375">
|
|
||||||
<defs
|
|
||||||
id="defs4377">
|
|
||||||
<linearGradient
|
|
||||||
x1="-403.07309"
|
|
||||||
y1="-40.681377"
|
|
||||||
x2="-560.61346"
|
|
||||||
y2="-32.881535"
|
|
||||||
id="linearGradient4343"
|
|
||||||
xlink:href="#linearGradient3354-9"
|
|
||||||
gradientUnits="userSpaceOnUse" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3354-9">
|
|
||||||
<stop
|
|
||||||
id="stop3356-9"
|
|
||||||
style="stop-color:#959595;stop-opacity:1"
|
|
||||||
offset="0" />
|
|
||||||
<stop
|
|
||||||
id="stop3358-9"
|
|
||||||
style="stop-color:#cccccc;stop-opacity:1"
|
|
||||||
offset="1" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
x1="-403.07309"
|
|
||||||
y1="-40.681377"
|
|
||||||
x2="-560.61346"
|
|
||||||
y2="-32.881535"
|
|
||||||
id="linearGradient3269"
|
|
||||||
xlink:href="#linearGradient3354-9"
|
|
||||||
gradientUnits="userSpaceOnUse" />
|
|
||||||
</defs>
|
|
||||||
<metadata
|
|
||||||
id="metadata4380">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
transform="translate(215.61577,-659.72777)"
|
|
||||||
id="layer1">
|
|
||||||
<g
|
|
||||||
transform="matrix(0.95410088,0,0,1.0481072,336.12082,766.65951)"
|
|
||||||
id="text3109-8-2-3-2"
|
|
||||||
style="font-size:118.26729584px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#4d4d4d;fill-opacity:1;stroke:none;font-family:Century Gothic;-inkscape-font-specification:Century Gothic Bold">
|
|
||||||
<path
|
|
||||||
d="m -192.30737,-56.190303 15.93837,0 0,30.259797 c -2e-5,5.890292 0.40421,9.990375 1.2127,12.300261 0.80844,2.271427 2.09814,4.042355 3.8691,5.3127882 1.8094,1.2704632 4.02306,1.9056873 6.64098,1.9056742 2.61786,1.31e-5 4.83152,-0.6159618 6.64099,-1.8479265 1.84788,-1.2704333 3.21458,-3.1183579 4.10009,-5.5437799 0.65442,-1.809405 0.98166,-5.678498 0.98171,-11.607288 l 0,-30.779526 15.82287,0 0,26.621691 c -6e-5,10.972089 -0.86628,18.479283 -2.59865,22.5216047 -2.11747,4.9278127 -5.23585,8.7199081 -9.35513,11.3762975 -4.11938,2.6178955 -9.35517,3.9268422 -15.70737,3.9268438 -6.89126,-1.6e-6 -12.47353,-1.5399388 -16.74684,-4.6198163 -4.23484,-3.07987137 -7.21847,-7.3724463 -8.95089,-12.8777377 -1.23196,-3.811329 -1.84793,-10.741046 -1.84793,-20.789173 l 0,-26.15971"
|
|
||||||
id="path2910-3"
|
|
||||||
style="fill:#4d4d4d" />
|
|
||||||
<path
|
|
||||||
d="m -130.62894,-56.190303 15.70737,0 0,6.409995 c 3.58033,-3.002821 6.8142,-5.081736 9.70161,-6.236752 2.92585,-1.193388 5.909485,-1.790114 8.950903,-1.790178 6.236704,6.4e-5 11.530238,2.175225 15.880619,6.52549 3.657292,3.695907 5.485968,9.162684 5.486031,16.400348 l 0,41.5205983 -15.591879,0 0,-27.5456543 c -4.9e-5,-7.507166 -0.346534,-12.492713 -1.039459,-14.956655 -0.65452,-2.463857 -1.828723,-4.331031 -3.52261,-5.601527 -1.655476,-1.308899 -3.71514,-1.963372 -6.179015,-1.963422 -3.1954,5e-5 -5.94804,1.078006 -8.25791,3.233871 -2.27144,2.117461 -3.84987,5.062591 -4.73531,8.835399 -0.46201,1.963458 -0.693,6.217534 -0.69298,12.762242 l 0,25.2357463 -15.70737,0 0,-62.8295013"
|
|
||||||
id="path2912-9"
|
|
||||||
style="fill:#4d4d4d" />
|
|
||||||
<path
|
|
||||||
d="m -58.382674,-82.061274 c 2.771873,8.9e-5 5.139526,1.001048 7.102968,3.002881 2.001897,2.002004 3.002856,4.427405 3.00288,7.276211 -2.4e-5,2.810463 -0.981734,5.216615 -2.945133,7.218462 -1.963441,1.963492 -4.311845,2.945202 -7.04522,2.945133 -2.810399,6.9e-5 -5.216551,-1.000891 -7.218462,-3.00288 -1.963427,-2.040346 -2.945137,-4.504245 -2.945133,-7.391706 -4e-6,-2.771809 0.981706,-5.139462 2.945133,-7.102968 1.963413,-1.963334 4.331066,-2.945044 7.102967,-2.945133 m -7.911435,25.870971 15.82287,0 0,62.8295013 -15.82287,0 0,-62.8295013"
|
|
||||||
id="path2914-9"
|
|
||||||
style="fill:#4d4d4d" />
|
|
||||||
<path
|
|
||||||
d="m 22.756753,-43.485808 -13.1087298,7.218463 c -2.4639564,-2.579352 -4.9086068,-4.369529 -7.3339592,-5.370536 -2.38695243,-1.000911 -5.1973376,-1.501391 -8.4311656,-1.501441 -5.8902994,5e-5 -10.6641044,1.770978 -14.3214284,5.312789 -3.618878,3.503402 -5.428304,8.007718 -5.428283,13.512962 -2.1e-5,5.351313 1.751657,9.720885 5.25504,13.108729 3.503331,3.3878798 8.103892,5.0818107 13.8016994,5.0817979 7.04517317,1.28e-5 12.5312,-2.4061391 16.4580968,-7.2184629 L 22.06378,-4.8525946 C 15.326486,3.8865605 5.8173728,8.2561324 -6.4635876,8.256134 -17.512676,8.2561324 -26.174822,4.9837658 -32.450051,-1.5609755 c -6.23676,-6.544725 -9.355133,-14.2059125 -9.355128,-22.9835855 -5e-6,-6.082721 1.520683,-11.684243 4.562068,-16.804582 3.041367,-5.120243 7.276194,-9.143329 12.704495,-12.06927 5.466754,-2.925821 11.568754,-4.388761 18.3060194,-4.388825 6.23670517,6.4e-5 11.838228,1.251263 16.8045846,3.7536 4.96624,2.463961 9.027824,5.986567 12.184765,10.56783"
|
|
||||||
id="path2916-7"
|
|
||||||
style="fill:#4d4d4d" />
|
|
||||||
<path
|
|
||||||
d="m 61.798097,-57.807238 c 5.928721,6.4e-5 11.491744,1.482254 16.689087,4.446573 5.235731,2.964439 9.316569,6.987525 12.242523,12.06927 2.925814,5.08184 4.388768,10.567867 4.388838,16.458095 -7e-5,5.92879 -1.482264,11.472564 -4.446588,16.6313386 C 87.746013,-3.0431569 83.742165,0.99917828 78.660426,3.9250563 73.57858,6.8124412 67.977058,8.2561324 61.855845,8.256134 52.847175,8.2561324 45.147489,5.0607627 38.756764,-1.3299847 32.404509,-7.7592146 29.228388,-15.555147 29.228393,-24.717804 c -5e-6,-9.817069 3.599598,-17.997985 10.79882,-24.542774 6.313727,-5.697712 13.570681,-8.546596 21.770884,-8.54666 m 0.230991,14.841159 c -4.889338,5e-5 -8.970172,1.71323 -12.242513,5.139546 -3.233893,3.387906 -4.850827,7.738229 -4.850807,13.050981 -2e-5,5.466808 1.597664,9.894128 4.79306,13.281972 3.233842,3.3878795 7.314676,5.0818105 12.242513,5.0817974 4.927761,1.31e-5 9.027844,-1.7131671 12.30026,-5.1395454 3.272317,-3.426342 4.908505,-7.834413 4.908555,-13.224224 -5e-5,-5.389749 -1.616989,-9.759321 -4.850807,-13.108729 -3.19542,-3.387817 -7.295502,-5.081748 -12.300261,-5.081798"
|
|
||||||
id="path2918-0"
|
|
||||||
style="fill:#4d4d4d" />
|
|
||||||
<path
|
|
||||||
d="m 101.59025,-56.190303 13.51297,0 0,7.911436 c 1.46292,-3.118318 3.40709,-5.485972 5.83251,-7.102968 2.42538,-1.616872 5.08177,-2.425339 7.96919,-2.425403 2.04038,6.4e-5 4.17705,0.539042 6.40999,1.616935 l -4.90855,13.570711 c -1.84796,-0.923913 -3.36865,-1.385895 -4.56207,-1.385945 -2.42543,5e-5 -4.4851,1.501489 -6.179,4.504321 -1.65546,3.002923 -2.48318,8.893183 -2.48316,17.670797 l 0.0577,3.060628 0,25.4089893 -15.64963,0 0,-62.8295013"
|
|
||||||
id="path2920-3"
|
|
||||||
style="fill:#4d4d4d" />
|
|
||||||
<path
|
|
||||||
d="m 141.78656,-56.190303 15.70737,0 0,6.409995 c 3.58033,-3.002821 6.8142,-5.081736 9.70162,-6.236752 2.92584,-1.193388 5.90947,-1.790114 8.95089,-1.790178 6.2367,6.4e-5 11.53024,2.175225 15.88062,6.52549 3.65729,3.695907 5.48597,9.162684 5.48603,16.400348 l 0,41.5205983 -15.59188,0 0,-27.5456543 c -5e-5,-7.507166 -0.34653,-12.492713 -1.03946,-14.956655 -0.65452,-2.463857 -1.82872,-4.331031 -3.52261,-5.601527 -1.65547,-1.308899 -3.71514,-1.963372 -6.179,-1.963422 -3.19541,5e-5 -5.94805,1.078006 -8.25792,3.233871 -2.27144,2.117461 -3.84988,5.062591 -4.73532,8.835399 -0.462,1.963458 -0.69299,6.217534 -0.69297,12.762242 l 0,25.2357463 -15.70737,0 0,-62.8295013"
|
|
||||||
id="path2922-9"
|
|
||||||
style="fill:#4d4d4d" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="matrix(1.4868765,0,0,1.4868765,477.80324,740.33267)"
|
|
||||||
id="g2886-8"
|
|
||||||
style="fill:#4d4d4d;fill-opacity:1">
|
|
||||||
<text
|
|
||||||
x="-299.4765"
|
|
||||||
y="15.69857"
|
|
||||||
transform="scale(0.95410088,1.0481072)"
|
|
||||||
id="text3109-8-2-3-7-6"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-size:127.35551453px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#4d4d4d;fill-opacity:1;stroke:none;font-family:Palatino;-inkscape-font-specification:Palatino Bold"><tspan
|
|
||||||
x="-299.4765"
|
|
||||||
y="15.69857"
|
|
||||||
id="tspan2884-5"
|
|
||||||
style="font-size:127.35551453px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#4d4d4d;fill-opacity:1;font-family:Palatino;-inkscape-font-specification:Palatino Bold">g</tspan></text>
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
d="m -339.89735,-32.881535 a 120.17799,8.4974337 0 1 1 -240.35599,0 120.17799,8.4974337 0 1 1 240.35599,0 z"
|
|
||||||
transform="matrix(1.1060606,0,0,1.1060606,426.17959,848.32285)"
|
|
||||||
id="path3423-1"
|
|
||||||
style="opacity:0.26353838;fill:url(#linearGradient3269);fill-opacity:1;stroke:none" />
|
|
||||||
<path
|
|
||||||
d="m -100.65527,815.73848 c -2.57334,-0.81915 -2.58247,-1.18087 -0.21166,-8.37918 2.367628,-7.18862 1.282568,-13.86445 -3.10637,-19.11195 -5.96822,-7.13575 -8.84216,-13.22467 -9.75823,-20.67444 -0.78646,-6.3958 -1.03575,-6.90285 -3.6397,-7.40279 -1.74646,-0.33531 -4.15929,0.32877 -9.90965,2.72745 -8.36615,3.4898 -10.35876,5.02218 -12.33291,9.4843 -1.03707,2.34406 -1.16172,3.7482 -0.57348,6.45967 0.7183,3.31089 3.66212,8.64054 4.77653,8.64768 0.29081,0.002 1.89748,1.1023 3.57036,2.44541 2.77589,2.22869 2.96643,2.61592 2.18093,4.43265 -1.70673,3.94745 -5.76177,8.73342 -7.39962,8.73342 -0.91894,0 -4.67154,-2.62848 -8.80223,-6.16546 -8.11348,-6.94729 -8.45354,-7.64379 -9.29155,-19.03126 -0.99988,-13.58711 2.34128,-19.92818 17.22216,-32.68537 l 9.33328,-8.0013 0.5961,-4.8534 c 0.61452,-5.00328 -0.25183,-16.91684 -1.70841,-23.49298 -0.86051,-3.885 -3.7003,-7.58525 -6.39519,-8.33292 -2.93605,-0.8146 -4.65723,0.86613 -6.89082,6.72892 -2.40994,6.32567 -4.71315,8.53245 -8.90528,8.53245 -2.61108,0 -5.04774,-1.67029 -6.73027,-4.61349 -1.20562,-2.10894 -1.90545,-14.77861 -1.18473,-21.44783 0.34669,-3.20813 0.36656,-6.45629 0.0442,-7.21814 -0.52459,-1.23963 -5.04199,-3.92118 -15.69218,-9.31491 -1.93608,-0.98052 -4.19318,-2.30073 -5.01577,-2.93381 -0.82258,-0.63307 -2.95712,-1.79702 -4.74342,-2.58654 -4.0461,-1.78831 -14.59582,-7.95686 -13.60818,-7.95686 1.86847,0 9.78678,2.4371 14.00212,4.30958 2.57327,1.14308 5.0365,2.07831 5.47385,2.07831 0.43736,0 5.39838,1.59698 11.0245,3.54885 5.62613,1.95185 10.76835,3.54883 11.42716,3.54883 1.56481,0 1.81019,-1.35379 1.30876,-7.22052 -0.22777,-2.66503 -0.21772,-4.84552 0.0224,-4.84552 0.24005,0 1.27682,0.51453 2.3039,1.14339 3.13787,1.92125 9.88743,3.09794 17.82053,3.10678 7.58555,0.009 17.48687,1.51346 21.27112,3.23319 5.42864,2.46702 11.72565,10.17235 19.713658,24.12261 5.55341,9.69849 11.5205,13.80519 20.07216,13.81419 3.45705,0.004 12.6805,-1.42134 25.17062,-3.88871 10.29868,-2.03446 23.894192,-2.49173 29.171452,-0.98115 6.43791,1.8428 14.95039,6.76935 21.98861,12.72577 6.58741,5.57491 7.60197,6.81262 11.64852,14.21045 4.82928,8.82878 10.15926,21.37645 14.899,35.07479 0.67537,1.95185 2.10182,5.23512 3.1699,7.29614 2.84984,5.49914 2.70779,5.83455 -2.47093,5.83455 -5.62088,0 -8.25697,-0.88636 -11.94164,-4.01528 -3.534,-3.00098 -4.45715,-4.83696 -9.98855,-19.86556 -2.83329,-7.6979 -5.59135,-12.31728 -7.35421,-12.31728 -1.20786,0 -3.65266,8.24914 -3.65266,12.32476 0,2.89469 1.814,6.8052 6.50386,14.02068 7.61871,11.72159 11.62643,28.29168 10.02221,41.4373 l -0.69293,5.67814 -5.07747,0.21136 c -7.99385,0.33278 -7.91382,0.44389 -7.91382,-10.98681 0,-12.16922 -0.82877,-14.80464 -6.19901,-19.71247 -2.2306,-2.03853 -7.23508,-7.83031 -11.12107,-12.87062 -3.88602,-5.04032 -7.60749,-9.16422 -8.26995,-9.16422 -1.52225,0 -2.28133,4.14488 -2.36225,12.8988 -0.0532,5.76495 -0.28025,6.74074 -1.98112,8.5172 -4.611042,4.81598 -7.847772,13.58519 -9.843172,26.668 -0.44167,2.89579 -0.82033,3.43751 -2.6974,3.85899 -2.76002,0.61973 -10.40844,0.72118 -11.06755,0.14681 -0.56842,-0.49534 0.42766,-8.35904 2.68721,-21.21493 0.85765,-4.87965 1.79377,-11.42725 2.08028,-14.55022 0.51005,-5.55953 -0.62987,-15.97557 -1.97899,-18.08289 -0.56095,-0.8762 -3.4173,-1.06606 -16.77722,-1.11512 -8.85564,-0.0325 -18.56749,-0.32384 -21.58186,-0.64737 l -5.48072,-0.58825 0,2.43214 c 0,2.60447 0.66758,4.90008 5.1317,17.6466 1.57224,4.48928 3.85053,11.33318 5.06287,15.20868 l 2.20425,7.04637 -1.86007,5.72944 c -1.02305,3.15119 -2.54137,6.92717 -3.37407,8.39107 -1.46872,2.58204 -1.64095,2.65994 -5.76025,2.60558 -2.33545,-0.0308 -5.28634,-0.38711 -6.557538,-0.79175 z"
|
|
||||||
id="path3046-2-3-0"
|
|
||||||
style="fill:#499848;fill-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 12 KiB |
190
docs/make.bat
@ -1,190 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
|
|
||||||
REM Command file for Sphinx documentation
|
|
||||||
|
|
||||||
if "%SPHINXBUILD%" == "" (
|
|
||||||
set SPHINXBUILD=sphinx-build
|
|
||||||
)
|
|
||||||
set BUILDDIR=build
|
|
||||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
|
|
||||||
set I18NSPHINXOPTS=%SPHINXOPTS% source
|
|
||||||
if NOT "%PAPER%" == "" (
|
|
||||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
|
||||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "" goto help
|
|
||||||
|
|
||||||
if "%1" == "help" (
|
|
||||||
:help
|
|
||||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
|
||||||
echo. html to make standalone HTML files
|
|
||||||
echo. dirhtml to make HTML files named index.html in directories
|
|
||||||
echo. singlehtml to make a single large HTML file
|
|
||||||
echo. pickle to make pickle files
|
|
||||||
echo. json to make JSON files
|
|
||||||
echo. htmlhelp to make HTML files and a HTML help project
|
|
||||||
echo. qthelp to make HTML files and a qthelp project
|
|
||||||
echo. devhelp to make HTML files and a Devhelp project
|
|
||||||
echo. epub to make an epub
|
|
||||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
|
||||||
echo. text to make text files
|
|
||||||
echo. man to make manual pages
|
|
||||||
echo. texinfo to make Texinfo files
|
|
||||||
echo. gettext to make PO message catalogs
|
|
||||||
echo. changes to make an overview over all changed/added/deprecated items
|
|
||||||
echo. linkcheck to check all external links for integrity
|
|
||||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "clean" (
|
|
||||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
|
||||||
del /q /s %BUILDDIR%\*
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "html" (
|
|
||||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "dirhtml" (
|
|
||||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "singlehtml" (
|
|
||||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "pickle" (
|
|
||||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished; now you can process the pickle files.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "json" (
|
|
||||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished; now you can process the JSON files.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "htmlhelp" (
|
|
||||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
|
||||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "qthelp" (
|
|
||||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
|
||||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
|
||||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Gunicorn.qhcp
|
|
||||||
echo.To view the help file:
|
|
||||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Gunicorn.ghc
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "devhelp" (
|
|
||||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "epub" (
|
|
||||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "latex" (
|
|
||||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "text" (
|
|
||||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "man" (
|
|
||||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "texinfo" (
|
|
||||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "gettext" (
|
|
||||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "changes" (
|
|
||||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.The overview file is in %BUILDDIR%/changes.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "linkcheck" (
|
|
||||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Link check complete; look for any errors in the above output ^
|
|
||||||
or in %BUILDDIR%/linkcheck/output.txt.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "doctest" (
|
|
||||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
|
||||||
if errorlevel 1 exit /b 1
|
|
||||||
echo.
|
|
||||||
echo.Testing of doctests in the sources finished, look at the ^
|
|
||||||
results in %BUILDDIR%/doctest/output.txt.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
:end
|
|
||||||
@ -1 +0,0 @@
|
|||||||
gunicorn.org
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#community">
|
|
||||||
<title>Green Unicorn - Community</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/index.html#community">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - Configuration</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - Configure</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,402 +0,0 @@
|
|||||||
html,body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,cite,
|
|
||||||
code,del,dfn,em,img,q,s,samp,small,strike,strong,sub,sup,tt,var,
|
|
||||||
dd,dl,dt,li,ol,ul,fieldset,form,label,legend,button,table,caption,
|
|
||||||
tbody,tfoot,thead,tr,th,td {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
font: inherit;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,ul {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
overflow-y: scroll;
|
|
||||||
font-size: 100%;
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
-ms-text-size-adjust: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover, a:active, a:focus {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
border: 0;
|
|
||||||
-ms-interpolation-mode: bicubic;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: #F8F8F3;
|
|
||||||
margin: 0;
|
|
||||||
font: 14px/1.4 "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
|
||||||
color: #67686B;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
a,
|
|
||||||
a:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clearall {
|
|
||||||
clear: both;
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
visibility: hidden;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-wrapper {
|
|
||||||
border-bottom: 1px solid #2A8729;
|
|
||||||
}
|
|
||||||
|
|
||||||
.latest {
|
|
||||||
width: 150px;
|
|
||||||
top: 0;
|
|
||||||
display: block;
|
|
||||||
float: right;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.logo-div {
|
|
||||||
width: 1000px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 5px;
|
|
||||||
height: 72px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: 250px;
|
|
||||||
margin: 0 auto;
|
|
||||||
height: 119px;
|
|
||||||
background: url(../images/logo-bottom.png) no-repeat bottom center;
|
|
||||||
position: relative;
|
|
||||||
z-index: 99999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner-wrapper {
|
|
||||||
background: url(../images/banner-bg.jpg) repeat;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
min-height: 365px;
|
|
||||||
margin-top: 1px;
|
|
||||||
margin-bottom: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner {
|
|
||||||
width: 1000px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
width: 250px;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: 32px;
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner h1 {
|
|
||||||
font-size: 20px;
|
|
||||||
color: #FFF;
|
|
||||||
margin: 15px 10px 0;
|
|
||||||
padding: 5px 40px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.greenbutton {
|
|
||||||
background: url(../images/greenbutton.jpg) repeat-x;
|
|
||||||
height: 54px;
|
|
||||||
width: 224px;
|
|
||||||
line-height: 54px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: solid 1px #1D692D;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 22px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-shadow: 1px 1px 1px #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.greenbutton:hover {
|
|
||||||
background: url(../images/greenbutton.jpg) repeat-x bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redbutton {
|
|
||||||
background: url(../images/redbutton.jpg) repeat-x;
|
|
||||||
height: 54px;
|
|
||||||
width: 224px;
|
|
||||||
line-height: 54px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: solid 1px #7D180A;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 22px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-shadow: 1px 1px 1px #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redbutton:hover {
|
|
||||||
background: url(../images/redbutton.jpg) repeat-x bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner-button {
|
|
||||||
width: 460px;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner-link {
|
|
||||||
width: 250px;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: 15px;
|
|
||||||
padding: 5px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner-link a {
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner-link a:hover {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mid-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
border-top: 1px solid #2A8729;
|
|
||||||
padding-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs {
|
|
||||||
width: 1000px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 3px;
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-bar li {
|
|
||||||
width: 230px;
|
|
||||||
padding: 3px;
|
|
||||||
text-align: center;
|
|
||||||
float: left;
|
|
||||||
margin-right: 5px;
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-bar li a {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-bar li a:hover > p,
|
|
||||||
.tab-bar li a:hover > h2 {
|
|
||||||
color: #1D692D;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-bar li a p,
|
|
||||||
.tab-bar li a h2 {
|
|
||||||
color: #404028;
|
|
||||||
margin-top: 8px;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-bar li a h2 {
|
|
||||||
font-weight: 700;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.withborder {
|
|
||||||
background: url(../images/separator.jpg) no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gabout, .gcommunity, .gdownloads, .gdocuments {
|
|
||||||
height: 80px;
|
|
||||||
width: 230px;
|
|
||||||
padding-top: 118px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gabout {
|
|
||||||
background: url(../images/about.jpg) no-repeat 50% 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcommunity {
|
|
||||||
background: url(../images/community.jpg) no-repeat 50% 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gdocuments {
|
|
||||||
background: url(../images/documents.jpg) no-repeat 50% 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gdownloads {
|
|
||||||
background: url(../images/downloads.jpg) no-repeat 50% 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs li.active a,
|
|
||||||
.gabout:hover,
|
|
||||||
.gcommunity:hover,
|
|
||||||
.gdocuments:hover,
|
|
||||||
.gdownloads:hover {
|
|
||||||
background-position: 50% -220px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs div {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs div.active {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-box {
|
|
||||||
color: #3F3F27;
|
|
||||||
border: 1px solid #DDDDD5;
|
|
||||||
padding: 25px 35px;
|
|
||||||
position: relative;
|
|
||||||
margin-top: 20px;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-box h1 {
|
|
||||||
font-size: 28px;
|
|
||||||
color: #2A8729;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-box p {
|
|
||||||
margin: 0 0 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-box ul {
|
|
||||||
padding-left: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-box li {
|
|
||||||
list-style: disc;
|
|
||||||
margin: 0 0 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-box a,
|
|
||||||
.latest a {
|
|
||||||
color: #3F3F27;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-box a:hover,
|
|
||||||
.latest a:hover {
|
|
||||||
color: #1D692D;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow {
|
|
||||||
background: url(../images/arrow.png) no-repeat;
|
|
||||||
position: absolute;
|
|
||||||
left: 115px;
|
|
||||||
top: -7px;
|
|
||||||
height: 10px;
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333333;
|
|
||||||
display: block;
|
|
||||||
padding: 8.5px;
|
|
||||||
margin: 0 0 9px;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 18px;
|
|
||||||
word-break: break-all;
|
|
||||||
word-wrap: break-word;
|
|
||||||
white-space: pre;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
background-color: #EEFFCC;
|
|
||||||
border-top: 1px solid #A9CC99;
|
|
||||||
border-bottom: 1px solid #A9CC99;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-wrapper {
|
|
||||||
background: url(../images/banner-bg.jpg) repeat;
|
|
||||||
height: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.users {
|
|
||||||
width: 1000px;
|
|
||||||
padding: 20px 5px;
|
|
||||||
margin: 0 auto;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.users h3 {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-left: 5px;
|
|
||||||
padding-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.users h2 {
|
|
||||||
font-size: 26px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.users .left-details {
|
|
||||||
width: 120px;
|
|
||||||
float: left;
|
|
||||||
height: 66px;
|
|
||||||
background: url(../images/footer-arrow.png) no-repeat top right;
|
|
||||||
padding-right: 15px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.users .company-logos {
|
|
||||||
float: left;
|
|
||||||
width: 820px;
|
|
||||||
height: 70px;
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.users .company-logos a img {
|
|
||||||
float: left;
|
|
||||||
border: solid 1px #004000;
|
|
||||||
margin: 0 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.users .company-logos a:hover img {
|
|
||||||
border: solid 1px #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
background-color: #F8F8F3;
|
|
||||||
display: block;
|
|
||||||
height: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer .footer-wp {
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 15px 5px;
|
|
||||||
width: 930px;
|
|
||||||
background: url(../images/footer-logo.jpg) no-repeat 0 50%;
|
|
||||||
padding-left: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-wp a {
|
|
||||||
color: #3F3F27;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-wp a:hover {
|
|
||||||
color: #1D692D;
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#deployment">
|
|
||||||
<title>Green Unicorn - Deployment</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/index.html#deployment">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#deployment">
|
|
||||||
<title>Green Unicorn - Deployment</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/index.html#deployment">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - Design</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - FAQ</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 408 B |
|
Before Width: | Height: | Size: 611 B |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 255 B |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 335 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 440 B |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
@ -1,185 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>Gunicorn - Python WSGI HTTP Server for UNIX</title>
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
|
||||||
<link rel="shortcut icon" href="images/favicon.png" type="image/x-icon">
|
|
||||||
<link rel="alternate"
|
|
||||||
href="https://github.com/benoitc/gunicorn/commits/master.atom"
|
|
||||||
type="application/atom+xml" title="Gunicorn commits">
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="logo-wrapper">
|
|
||||||
<div class="logo-div">
|
|
||||||
<div class="latest">
|
|
||||||
Latest version: <strong><a
|
|
||||||
href="https://docs.gunicorn.org/en/stable/">23.0.0</a></strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="logo"><img src="images/logo.jpg" ></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="banner-wrapper">
|
|
||||||
<div class="banner">
|
|
||||||
<div class="title"><img src="images/title.png"></div>
|
|
||||||
<h1>Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.</h1>
|
|
||||||
<div class="banner-button">
|
|
||||||
<a href="https://github.com/benoitc/gunicorn" title="View source at github" class="greenbutton">View source</a>
|
|
||||||
<a href="http://pypi.python.org/pypi/gunicorn/" title="Download from PyPi" class="redbutton">Download</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mid-wrapper">
|
|
||||||
<div class="tabs">
|
|
||||||
<ul class="tab-bar">
|
|
||||||
<li class="active">
|
|
||||||
<a href="#quickstart" title="Quickstart" class="gabout">
|
|
||||||
<h2>Quickstart</h2>
|
|
||||||
<p>Read the quickstart guide to get started using Gunicorn.</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="withborder">
|
|
||||||
<a href="#deployment" title="Deployment" class="gdownloads">
|
|
||||||
<h2>Deployment</h2>
|
|
||||||
<p>Learn how to deploy the Gunicorn server.</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="withborder">
|
|
||||||
<a href="#community" title="Community" class="gcommunity">
|
|
||||||
<h2>Community</h2>
|
|
||||||
<p>Get in touch with the community.</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="withborder">
|
|
||||||
<a href="#docs" title="Documentation" class="gdocuments">
|
|
||||||
<h2>Documentation</h2>
|
|
||||||
<p>Read the documentation to learn more about Gunicorn.</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="clearall active"></div>
|
|
||||||
|
|
||||||
<div class="tab-box active" data-tab="quickstart">
|
|
||||||
<h1>Installation</h1>
|
|
||||||
<p>
|
|
||||||
Here's a quick rundown on how to get started with Gunicorn. For more details read the <a href="http://docs.gunicorn.org/en/stable/">documentation</a>.
|
|
||||||
</p>
|
|
||||||
<pre>
|
|
||||||
$ pip install gunicorn
|
|
||||||
$ cat myapp.py
|
|
||||||
def app(environ, start_response):
|
|
||||||
data = b"Hello, World!\n"
|
|
||||||
start_response("200 OK", [
|
|
||||||
("Content-Type", "text/plain"),
|
|
||||||
("Content-Length", str(len(data)))
|
|
||||||
])
|
|
||||||
return iter([data])
|
|
||||||
$ gunicorn -w 4 myapp:app
|
|
||||||
[2014-09-10 10:22:28 +0000] [30869] [INFO] Listening at: http://127.0.0.1:8000 (30869)
|
|
||||||
[2014-09-10 10:22:28 +0000] [30869] [INFO] Using worker: sync
|
|
||||||
[2014-09-10 10:22:28 +0000] [30874] [INFO] Booting worker with pid: 30874
|
|
||||||
[2014-09-10 10:22:28 +0000] [30875] [INFO] Booting worker with pid: 30875
|
|
||||||
[2014-09-10 10:22:28 +0000] [30876] [INFO] Booting worker with pid: 30876
|
|
||||||
[2014-09-10 10:22:28 +0000] [30877] [INFO] Booting worker with pid: 30877
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
<div class="tab-box" data-tab="deployment">
|
|
||||||
<h1>Deployment</h1>
|
|
||||||
<p>
|
|
||||||
Gunicorn is a WSGI HTTP server. It is best to use Gunicorn behind an HTTP proxy server. We strongly advise you to use <a href="http://www.nginx.org/">nginx</a>.
|
|
||||||
</p>
|
|
||||||
<p>Here's an example to help you get started with using nginx:</p>
|
|
||||||
<pre>
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name example.org;
|
|
||||||
access_log /var/log/nginx/example.log;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:8000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
<p>Nginx is set up as reverse proxy server to a Gunicorn server running on localhost port 8000.</p>
|
|
||||||
<p>Read the full documentation at <a
|
|
||||||
href="http://docs.gunicorn.org/en/latest/deploy.html">docs.gunicorn.org</a></p>
|
|
||||||
</div>
|
|
||||||
<div class="tab-box" data-tab="community">
|
|
||||||
<h1>Project Management</h1>
|
|
||||||
<p><strong>Gunicorn</strong> uses <a href="https://github.com/benoitc/gunicorn/projects">GitHub for the project management</a>. GitHub issues are used for 3 different purposes:</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/benoitc/gunicorn/projects/2">Bug tracker</a></li>
|
|
||||||
<li><a href="https://github.com/benoitc/gunicorn/projects/4">Forum</a></li>
|
|
||||||
<li><a href="https://github.com/benoitc/gunicorn/projects/3">Mailing list</a>
|
|
||||||
</ul>
|
|
||||||
<p>Project maintenance guidelines are available on the <a href="https://github.com/benoitc/gunicorn/wiki/Project-management">wiki</a></p>
|
|
||||||
|
|
||||||
<h1>IRC</h1>
|
|
||||||
<p>The Gunicorn channel is on the <a href="https://libera.chat/">Libera Chat</a> IRC
|
|
||||||
network. You can chat with the community on the <a href="https://web.libera.chat/?channels=#gunicorn">#gunicorn channel</a>.</p>
|
|
||||||
|
|
||||||
<h1>Issue Tracking</h1>
|
|
||||||
<p>Bug reports, enhancement requests and tasks generally go in the <a href="http://github.com/benoitc/gunicorn/issues">Github
|
|
||||||
issue tracker</a>.</p>
|
|
||||||
|
|
||||||
<h1>Security Issues</h1>
|
|
||||||
<p>The security mailing list is a place to report security issues. Only
|
|
||||||
developers are subscribed to it. To post a message to the list use the
|
|
||||||
address <a href="mailto:security@gunicorn.org">security@gunicorn.org</a></p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="tab-box" data-tab="docs">
|
|
||||||
<h1>Documentation</h1>
|
|
||||||
<p>You can read more comprehensive documentation at <a href="http://docs.gunicorn.org">docs.gunicorn.org</a>.</p>
|
|
||||||
<p>The contents are:</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="http://docs.gunicorn.org/en/latest/install.html">Installation</a></li>
|
|
||||||
<li><a
|
|
||||||
href="http://docs.gunicorn.org/en/latest/run.html">Running
|
|
||||||
Gunicorn</a></li>
|
|
||||||
<li><a
|
|
||||||
href="http://docs.gunicorn.org/en/latest/configure.html">Configuration
|
|
||||||
Overview</a></li>
|
|
||||||
<li><a href="http://docs.gunicorn.org/en/latest/deploy.html">Deploying Gunicorn</a></li>
|
|
||||||
<li><a href="http://docs.gunicorn.org/en/latest/design.html">Design</a></li>
|
|
||||||
<li><a href="http://docs.gunicorn.org/en/latest/faq.html">FAQ</a></li>
|
|
||||||
<li><a href="http://docs.gunicorn.org/en/latest/news.html">Changelog</a></li>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div class="user-wrapper">
|
|
||||||
<div class="users">
|
|
||||||
<div class="left-details">
|
|
||||||
<h3>Who is using</h3>
|
|
||||||
<h2>Gunicorn</h2>
|
|
||||||
</div>
|
|
||||||
<div class="company-logos">
|
|
||||||
<a href="#"><img src="images/user1.jpg"></a>
|
|
||||||
<a href="#"><img src="images/user1.jpg"></a>
|
|
||||||
<a href="#"><img src="images/user1.jpg"></a>
|
|
||||||
<a href="#"><img src="images/user1.jpg"></a>
|
|
||||||
<a href="#"><img src="images/user1.jpg"></a>
|
|
||||||
<a href="#"><img src="images/user1.jpg"></a>
|
|
||||||
</div>
|
|
||||||
<div class="clearall"></div>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<div class="footer">
|
|
||||||
<div class="footer-wp">
|
|
||||||
This open sourced site is hosted on GitHub. <br>
|
|
||||||
<a href="http://github.com/benoitc/gunicorn/issues">Patches, suggestions, and comments are welcome.</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
|
|
||||||
<script src="js/main.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - Install</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - Install</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
$(document).ready(function() {
|
|
||||||
Tabs.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
var Tabs = {
|
|
||||||
init: function(){
|
|
||||||
var activateTab = function ($tab) {
|
|
||||||
var // this links tabs set
|
|
||||||
$tabs = $tab.parents('.tabs'),
|
|
||||||
// currently active tab
|
|
||||||
activeTab = {
|
|
||||||
'tab' : $tabs.find('ul').children('li.active'),
|
|
||||||
'content' : $tabs.find('div[data-tab].active')
|
|
||||||
},
|
|
||||||
// newly clicked tab
|
|
||||||
newTab = {
|
|
||||||
'tab' : $tab.parent('li'),
|
|
||||||
'content' : $tabs.find('[data-tab=' + $tab.attr('href').replace('#', '') + ']')
|
|
||||||
},
|
|
||||||
x, y;
|
|
||||||
|
|
||||||
// remove active class from tab and content
|
|
||||||
for (x in activeTab) {
|
|
||||||
activeTab[x].removeClass('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
// add active class to tab and content
|
|
||||||
for (y in newTab) {
|
|
||||||
newTab[y].addClass('active');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// hook up tab links
|
|
||||||
$(document).on('click', '.tabs ul li a', function(e) {
|
|
||||||
activateTab($(this));
|
|
||||||
//alert($(this));
|
|
||||||
});
|
|
||||||
|
|
||||||
// hook up initial load active tab
|
|
||||||
if (window.location.hash) {
|
|
||||||
var $activeTab = $('a[href="' + window.location.hash + '"]');
|
|
||||||
if ($activeTab.length && $activeTab.parents('.tabs').length) {
|
|
||||||
activateTab($activeTab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - News</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - Run</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/</loc>
|
|
||||||
<lastmod>2019-11-27T00:02:48+01:00</lastmod>
|
|
||||||
<priority>1.0</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/community.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/configuration.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/configure.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/deploy.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/deployment.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/design.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/faq.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/install.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/installation.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/news.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/run.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/tuning.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>http://gunicorn.org/usage.html</loc>
|
|
||||||
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
|
|
||||||
<priority>0.5</priority>
|
|
||||||
</url>
|
|
||||||
</urlset>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - FAQ</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
|
|
||||||
<title>Green Unicorn - Run</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>
|
|
||||||
Redirecting to <a href="http://gunicorn.org/">here</a>
|
|
||||||
</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import os
|
|
||||||
import subprocess
|
|
||||||
from xml.etree import ElementTree
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
generate(
|
|
||||||
site_path=os.path.join(os.path.dirname(__file__), 'site'),
|
|
||||||
special_priorities={'index.html': 1.0})
|
|
||||||
|
|
||||||
|
|
||||||
def generate(site_path, special_priorities, directory_index='index.html'):
|
|
||||||
urlset = ElementTree.Element('urlset', xmlns='http://www.sitemaps.org/schemas/sitemap/0.9')
|
|
||||||
urlset.text = '\n '
|
|
||||||
for root, dirs, filenames in os.walk(site_path):
|
|
||||||
for filename in filenames:
|
|
||||||
if filename.endswith('.html'):
|
|
||||||
absolute_filepath = os.path.join(root, filename)
|
|
||||||
relative_path = os.path.relpath(absolute_filepath, site_path)
|
|
||||||
relative_url = os.path.dirname(relative_path) if filename == directory_index else relative_path
|
|
||||||
last_modification = subprocess.check_output(
|
|
||||||
['git', 'log', '-1', '--pretty="%cI"', absolute_filepath]).decode('ascii').strip('\n"')
|
|
||||||
url_element = ElementTree.SubElement(urlset, 'url')
|
|
||||||
loc_element = ElementTree.SubElement(url_element, 'loc')
|
|
||||||
loc_element.text = 'http://gunicorn.org/' + relative_url
|
|
||||||
lastmod_element = ElementTree.SubElement(url_element, 'lastmod')
|
|
||||||
lastmod_element.text = last_modification
|
|
||||||
priority_element = ElementTree.SubElement(url_element, 'priority')
|
|
||||||
priority_element.text = str(special_priorities.get(relative_path, 0.5))
|
|
||||||
url_element.tail = priority_element.tail = '\n '
|
|
||||||
url_element.text = loc_element.tail = lastmod_element.tail = '\n '
|
|
||||||
# We sort the url nodes instead of the filenames because
|
|
||||||
# filenames might be altered by the directory_index option
|
|
||||||
urlset[:] = sorted([url for url in urlset], key=lambda url: url[0].text)
|
|
||||||
urlset.tail = urlset[-1].tail = '\n'
|
|
||||||
with open(os.path.join(site_path, 'sitemap.xml'), 'wb') as sitemap_file:
|
|
||||||
ElementTree.ElementTree(urlset).write(sitemap_file, encoding='UTF-8', xml_declaration=True)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
@ -1,211 +0,0 @@
|
|||||||
Changelog - 2010
|
|
||||||
================
|
|
||||||
|
|
||||||
0.12.0 / 2010-12-22
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Add support for logging configuration using a ini file.
|
|
||||||
It uses the standard Python logging's module Configuration
|
|
||||||
file format and allows anyone to use his custom file handler
|
|
||||||
- Add IPV6 support
|
|
||||||
- Add multidomain application example
|
|
||||||
- Improve gunicorn_django command when importing settings module
|
|
||||||
using DJANGO_SETTINGS_MODULE environment variable
|
|
||||||
- Send appropriate error status on http parsing
|
|
||||||
- Fix pidfile, set permissions so other user can read
|
|
||||||
it and use it.
|
|
||||||
- Fix temporary file leaking
|
|
||||||
- Fix setpgrp issue, can now be launched via ubuntu upstart
|
|
||||||
- Set the number of workers to zero on WINCH
|
|
||||||
|
|
||||||
0.11.2 / 2010-10-30
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Add SERVER_SOFTWARE to the os.environ
|
|
||||||
* Add support for django settings environment variable
|
|
||||||
* Add support for logging configuration in Paster ini-files
|
|
||||||
* Improve arbiter notification in asynchronous workers
|
|
||||||
* Display the right error when a worker can't be used
|
|
||||||
* Fix Django support
|
|
||||||
* Fix HUP with Paster applications
|
|
||||||
* Fix readline in wsgi.input
|
|
||||||
|
|
||||||
0.11.1 / 2010-09-02
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Implement max-requests feature to prevent memory leaks.
|
|
||||||
* Added 'worker_exit' server hook.
|
|
||||||
* Reseed the random number generator after fork().
|
|
||||||
* Improve Eventlet worker.
|
|
||||||
* Fix Django command `run_gunicorn`.
|
|
||||||
* Fix the default proc name internal setting.
|
|
||||||
* Workaround to prevent Gevent worker to segfault on MacOSX.
|
|
||||||
|
|
||||||
0.11.0 / 2010-08-12
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Improve dramatically performances of Gevent and Eventlet workers
|
|
||||||
* Optimize HTTP parsing
|
|
||||||
* Drop Server and Date headers in start_response when provided.
|
|
||||||
* Fix latency issue in async workers
|
|
||||||
|
|
||||||
0.10.1 / 2010-08-06
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Improve gevent's workers. Add "egg:gunicorn#gevent_wsgi" worker using
|
|
||||||
`gevent.wsgi <http://www.gevent.org/gevent.wsgi.html>`_ and
|
|
||||||
"egg:gunicorn#gevent_pywsgi" worker using `gevent.pywsgi
|
|
||||||
<http://www.gevent.org/gevent.pywsgi.html>`_ .
|
|
||||||
**"egg:gunicorn#gevent"** using our own HTTP parser is still here and
|
|
||||||
is **recommended** for normal uses. Use the "gevent.wsgi" parser if you
|
|
||||||
need really fast connections and don't need streaming, keepalive or ssl.
|
|
||||||
* Add pre/post request hooks
|
|
||||||
* Exit more quietly
|
|
||||||
* Fix gevent dns issue
|
|
||||||
|
|
||||||
0.10.0 / 2010-07-08
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* New HTTP parser.
|
|
||||||
* New HUP behaviour. Re-reads the configuration and then reloads all
|
|
||||||
worker processes without changing the master process id. Helpful for
|
|
||||||
code reloading and monitoring applications like supervisord and runit.
|
|
||||||
* Added a preload configuration parameter. By default, application code
|
|
||||||
is now loaded after a worker forks. This couple with the new HUP
|
|
||||||
handling can be used for dev servers to do hot code reloading. Using
|
|
||||||
the preload flag can help a bit in small memory VM's.
|
|
||||||
* Allow people to pass command line arguments to WSGI applications. See:
|
|
||||||
`examples/alt_spec.py
|
|
||||||
<http://github.com/benoitc/gunicorn/raw/master/examples/alt_spec.py>`_
|
|
||||||
* Added an example gevent reloader configuration:
|
|
||||||
`examples/example_gevent_reloader.py
|
|
||||||
<http://github.com/benoitc/gunicorn/blob/master/examples/example_gevent_reloader.py>`_.
|
|
||||||
* New gevent worker "egg:gunicorn#gevent2", working with gevent.wsgi.
|
|
||||||
* Internal refactoring and various bug fixes.
|
|
||||||
* New documentation website.
|
|
||||||
|
|
||||||
0.9.1 / 2010-05-26
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Support https via X-Forwarded-Protocol or X-Forwarded-Ssl headers
|
|
||||||
* Fix configuration
|
|
||||||
* Remove -d options which was used instead of -D for daemon.
|
|
||||||
* Fix umask in unix socket
|
|
||||||
|
|
||||||
0.9.0 / 2010-05-24
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Added *when_ready* hook. Called just after the server is started
|
|
||||||
* Added *preload* setting. Load application code before the worker processes
|
|
||||||
are forked.
|
|
||||||
* Refactored Config
|
|
||||||
* Fix pidfile
|
|
||||||
* Fix QUIT/HUP in async workers
|
|
||||||
* Fix reexec
|
|
||||||
* Documentation improvements
|
|
||||||
|
|
||||||
0.8.1 / 2010-04-29
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Fix builtins import in config
|
|
||||||
* Fix installation with pip
|
|
||||||
* Fix Tornado WSGI support
|
|
||||||
* Delay application loading until after processing all configuration
|
|
||||||
|
|
||||||
0.8.0 / 2010-04-22
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Refactored Worker management for better async support. Now use the -k option
|
|
||||||
to set the type of request processing to use
|
|
||||||
* Added support for Tornado_
|
|
||||||
|
|
||||||
0.7.2 / 2010-04-15
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Added --spew option to help debugging (installs a system trace hook)
|
|
||||||
* Some fixes in async arbiters
|
|
||||||
* Fix a bug in start_response on error
|
|
||||||
|
|
||||||
0.7.1 / 2010-04-01
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Fix bug when responses have no body.
|
|
||||||
|
|
||||||
0.7.0 / 2010-03-26
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Added support for Eventlet_ and Gevent_ based workers.
|
|
||||||
* Added Websockets_ support
|
|
||||||
* Fix Chunked Encoding
|
|
||||||
* Fix SIGWINCH on OpenBSD_
|
|
||||||
* Fix `PEP 333`_ compliance for the write callable.
|
|
||||||
|
|
||||||
0.6.5 / 2010-03-11
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Fix pidfile handling
|
|
||||||
* Fix Exception Error
|
|
||||||
|
|
||||||
0.6.4 / 2010-03-08
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Use cStringIO for performance when possible.
|
|
||||||
* Fix worker freeze when a remote connection closes unexpectedly.
|
|
||||||
|
|
||||||
0.6.3 / 2010-03-07
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Make HTTP parsing faster.
|
|
||||||
* Various bug fixes
|
|
||||||
|
|
||||||
0.6.2 / 2010-03-01
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Added support for chunked response.
|
|
||||||
* Added proc_name option to the config file.
|
|
||||||
* Improved the HTTP parser. It now uses buffers instead of strings to store
|
|
||||||
temporary data.
|
|
||||||
* Improved performance when sending responses.
|
|
||||||
* Workers are now murdered by age (the oldest is killed first).
|
|
||||||
|
|
||||||
0.6.1 / 2010-02-24
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Added gunicorn config file support for Django admin command
|
|
||||||
* Fix gunicorn config file. -c was broken.
|
|
||||||
* Removed TTIN/TTOU from workers which blocked other signals.
|
|
||||||
|
|
||||||
0.6.0 / 2010-02-22
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Added setproctitle support
|
|
||||||
* Change privilege switch behavior. We now work like NGINX, master keeps the
|
|
||||||
permissions, new uid/gid permissions are only set for workers.
|
|
||||||
|
|
||||||
0.5.1 / 2010-02-22
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Fix umask
|
|
||||||
* Added Debian packaging
|
|
||||||
|
|
||||||
0.5.0 / 2010-02-20
|
|
||||||
------------------
|
|
||||||
|
|
||||||
* Added `configuration file <configuration.html>`_ handler.
|
|
||||||
* Added support for pre/post fork hooks
|
|
||||||
* Added support for before_exec hook
|
|
||||||
* Added support for unix sockets
|
|
||||||
* Added launch of workers processes under different user/group
|
|
||||||
* Added umask option
|
|
||||||
* Added SCRIPT_NAME support
|
|
||||||
* Better support of some exotic settings for Django projects
|
|
||||||
* Better support of Paste-compatible applications
|
|
||||||
* Some refactoring to make the code easier to hack
|
|
||||||
* Allow multiple keys in request and response headers
|
|
||||||
|
|
||||||
.. _Tornado: http://www.tornadoweb.org/
|
|
||||||
.. _`PEP 333`: https://www.python.org/dev/peps/pep-0333/
|
|
||||||
.. _Eventlet: http://eventlet.net/
|
|
||||||
.. _Gevent: http://www.gevent.org/
|
|
||||||
.. _OpenBSD: https://www.openbsd.org/
|
|
||||||
.. _Websockets: https://html.spec.whatwg.org/multipage/web-sockets.html
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
Changelog - 2011
|
|
||||||
================
|
|
||||||
|
|
||||||
0.13.4 / 2011-09-23
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- fix util.closerange function used to prevent leaking fds on python 2.5
|
|
||||||
(typo)
|
|
||||||
|
|
||||||
0.13.3 / 2011-09-19
|
|
||||||
-------------------
|
|
||||||
- refactor gevent worker
|
|
||||||
- prevent leaking fds on reexec
|
|
||||||
- fix inverted request_time computation
|
|
||||||
|
|
||||||
0.13.2 / 2011-09-17
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Add support for Tornado 2.0 in tornado worker
|
|
||||||
- Improve access logs: allows customisation of the log format & add
|
|
||||||
request time
|
|
||||||
- Logger module is now pluggable
|
|
||||||
- Improve graceful shutdown in Python versions >= 2.6
|
|
||||||
- Fix post_request root arity for compatibility
|
|
||||||
- Fix sendfile support
|
|
||||||
- Fix Django reloading
|
|
||||||
|
|
||||||
0.13.1 / 2011-08-22
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Fix unix socket. log argument was missing.
|
|
||||||
|
|
||||||
0.13.0 / 2011-08-22
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Improve logging: allows file-reopening and add access log file
|
|
||||||
compatible with the `apache combined log format <http://httpd.apache.org/docs/2.0/logs.html#combined>`_
|
|
||||||
- Add the possibility to set custom SSL headers. X-Forwarded-Protocol
|
|
||||||
and X-Forwarded-SSL are still the default
|
|
||||||
- New `on_reload` hook to customize how gunicorn spawn new workers on
|
|
||||||
SIGHUP
|
|
||||||
- Handle projects with relative path in django_gunicorn command
|
|
||||||
- Preserve path parameters in PATH_INFO
|
|
||||||
- post_request hook now accepts the environ as argument.
|
|
||||||
- When stopping the arbiter, close the listener asap.
|
|
||||||
- Fix Django command `run_gunicorn` in settings reloading
|
|
||||||
- Fix Tornado_ worker exiting
|
|
||||||
- Fix the use of sendfile in wsgi.file_wrapper
|
|
||||||
|
|
||||||
|
|
||||||
0.12.2 / 2011-05-18
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Add wsgi.file_wrapper optimised for FreeBSD, Linux & MacOSX (use
|
|
||||||
sendfile if available)
|
|
||||||
- Fix django run_gunicorn command. Make sure we reload the application
|
|
||||||
code.
|
|
||||||
- Fix django localisation
|
|
||||||
- Compatible with gevent 0.14dev
|
|
||||||
|
|
||||||
0.12.1 / 2011-03-23
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Add "on_starting" hook. This hook can be used to set anything before
|
|
||||||
the arbiter really start
|
|
||||||
- Support bdist_rpm in setup
|
|
||||||
- Improve content-length handling (pep 3333)
|
|
||||||
- Improve Django support
|
|
||||||
- Fix daemonizing (#142)
|
|
||||||
- Fix ipv6 handling
|
|
||||||
|
|
||||||
|
|
||||||
.. _Tornado: http://www.tornadoweb.org/
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
Changelog - 2012
|
|
||||||
================
|
|
||||||
|
|
||||||
0.17.0 / 2012-12-25
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- allows gunicorn to bind to multiple address
|
|
||||||
- add SSL support
|
|
||||||
- add syslog support
|
|
||||||
- add nworkers_changed hook
|
|
||||||
- add response arg for post_request hook
|
|
||||||
- parse command line with argparse (replace deprecated optparse)
|
|
||||||
- fix PWD detection in arbiter
|
|
||||||
- miscellaneous PEP8 fixes
|
|
||||||
|
|
||||||
0.16.1 / 2012-11-19
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Fix packaging
|
|
||||||
|
|
||||||
0.16.0 / 2012-11-19
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- **Added support for Python 3.2 & 3.3**
|
|
||||||
- Expose --pythonpath command to all gunicorn commands
|
|
||||||
- Honor $PORT environment variable, useful for deployment on heroku
|
|
||||||
- Removed support for Python 2.5
|
|
||||||
- Make sure we reopen the logs on the console
|
|
||||||
- Fix django settings module detection from path
|
|
||||||
- Reverted timeout for client socket. Fix issue on blocking issues.
|
|
||||||
- Fixed gevent worker
|
|
||||||
|
|
||||||
0.15.0 / 2012-10-18
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- new documentation site on http://docs.gunicorn.org
|
|
||||||
- new website on http://gunicorn.org
|
|
||||||
- add `haproxy PROXY protocol <http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt>`_ support
|
|
||||||
- add ForwardedAllowIPS option: allows to filter Front-end's IPs
|
|
||||||
allowed to handle X-Forwarded-* headers.
|
|
||||||
- add callable hooks for paster config
|
|
||||||
- add x-forwarded-proto as secure scheme default (Heroku is using this)
|
|
||||||
- allows gunicorn to load a pre-compiled application
|
|
||||||
- support file reopening & reexec for all loggers
|
|
||||||
- initialize the logging config file with defaults.
|
|
||||||
- set timeout for client socket (slow client DoS).
|
|
||||||
- NoMoreData, ChunkMissingTerminator, InvalidChunkSize are now
|
|
||||||
IOError exceptions
|
|
||||||
- fix graceful shutdown in gevent
|
|
||||||
- fix limit request line check
|
|
||||||
|
|
||||||
0.14.6 / 2012-07-26
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
|
|
||||||
- fix gevent & subproces
|
|
||||||
- fix request line length check
|
|
||||||
- fix keepalive = 0
|
|
||||||
- fix tornado worker
|
|
||||||
|
|
||||||
0.14.5 / 2012-06-24
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
- fix logging during daemonisation
|
|
||||||
|
|
||||||
0.14.4 / 2012-06-24
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- new --graceful-timeout option
|
|
||||||
- fix multiple issues with request limit
|
|
||||||
- more fixes in django settings resolutions
|
|
||||||
- fix gevent.core import
|
|
||||||
- fix keepalive=0 in eventlet worker
|
|
||||||
- fix handle_error display with the unix worker
|
|
||||||
- fix tornado.wsgi.WSGIApplication calling error
|
|
||||||
|
|
||||||
- **breaking change**: take the control on graceful reload back.
|
|
||||||
graceful can't be overridden anymore using the on_reload function.
|
|
||||||
|
|
||||||
0.14.3 / 2012-05-15
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- improvement: performance of http.body.Body.readline()
|
|
||||||
- improvement: log HTTP errors in access log like Apache
|
|
||||||
- improvement: display traceback when the worker fails to boot
|
|
||||||
- improvement: makes gunicorn work with gevent 1.0
|
|
||||||
- examples: websocket example now supports hybi13
|
|
||||||
- fix: reopen log files after initialization
|
|
||||||
- fix: websockets support
|
|
||||||
- fix: django1.4 support
|
|
||||||
- fix: only load the paster application 1 time
|
|
||||||
|
|
||||||
0.14.2 / 2012-03-16
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- add validate_class validator: allows to use a class or a method to
|
|
||||||
initialize the app during in-code configuration
|
|
||||||
- add support for max_requests in tornado worker
|
|
||||||
- add support for disabling x_forwarded_for_header in tornado worker
|
|
||||||
- gevent_wsgi is now an alias of gevent_pywsgi
|
|
||||||
- Fix gevent_pywsgi worker
|
|
||||||
|
|
||||||
0.14.1 / 2012-03-02
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- fixing source archive, reducing its size
|
|
||||||
|
|
||||||
0.14.0 / 2012-02-27
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- check if Request line is too large: You can now pass the parameter
|
|
||||||
``--limit-request-line`` or set the ``limit_request_line`` in your
|
|
||||||
configuration file to set the max size of the request line in bytes.
|
|
||||||
- limit the number of headers fields and their size. Add
|
|
||||||
``--limit-request-field`` and ``limit-request-field-size`` settings
|
|
||||||
- add ``p`` variable to the log access format to log pidfile
|
|
||||||
- add ``{HeaderName}o`` variable to the logo access format to log the
|
|
||||||
response header HeaderName
|
|
||||||
- request header is now logged with the variable ``{HeaderName}i`` in the
|
|
||||||
access log file
|
|
||||||
- improve error logging
|
|
||||||
- support logging.configFile
|
|
||||||
- support django 1.4 in both gunicorn_django & run_gunicorn command
|
|
||||||
- improve reload in django run_gunicorn command (should just work now)
|
|
||||||
- allows people to set the ``X-Forwarded-For`` header key and disable it by
|
|
||||||
setting an empty string.
|
|
||||||
- fix support of Tornado
|
|
||||||
- many other fixes.
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
Changelog - 2013
|
|
||||||
================
|
|
||||||
|
|
||||||
18.0 / 2013-08-26
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
- new: add ``-e/--env`` command line argument to pass an environment variables to
|
|
||||||
gunicorn
|
|
||||||
- new: add ``--chdir`` command line argument to specified directory
|
|
||||||
before apps loading. - new: add wsgi.file_wrapper support in async workers
|
|
||||||
- new: add ``--paste`` command line argument to set the paster config file
|
|
||||||
- deprecated: the command ``gunicorn_django`` is now deprecated. You should now
|
|
||||||
run your application with the WSGI interface installed with your project (see
|
|
||||||
https://docs.djangoproject.com/en/1.4/howto/deployment/wsgi/gunicorn/) for
|
|
||||||
more infos.
|
|
||||||
- deprecated: the command ``gunicorn_paste`` is deprecated. You now should use
|
|
||||||
the new ``--paste`` argument to set the configuration file of your paster
|
|
||||||
application.
|
|
||||||
- fix: Removes unmatched leading quote from the beginning of the default access
|
|
||||||
log format string
|
|
||||||
- fix: null timeout
|
|
||||||
- fix: gevent worker
|
|
||||||
- fix: don't reload the paster app when using pserve
|
|
||||||
- fix: after closing for error do not keep alive the connection
|
|
||||||
- fix: responses 1xx, 204 and 304 should not force the connection to be closed
|
|
||||||
|
|
||||||
17.5 / 2013-07-03
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- new: add signals documentation
|
|
||||||
- new: add post_worker_init hook for workers
|
|
||||||
- new: try to use gunicorn.conf.py in current folder as the default
|
|
||||||
config file.
|
|
||||||
- fix graceful timeout with the Eventlet worker
|
|
||||||
- fix: don't raise an error when closing the socket if already closed
|
|
||||||
- fix: fix --settings parameter for django application and try to find
|
|
||||||
the django settings when using the ``gunicorn`` command.
|
|
||||||
- fix: give the initial global_conf to paster application
|
|
||||||
- fix: fix 'Expect: 100-continue' support on Python 3
|
|
||||||
|
|
||||||
New versioning:
|
|
||||||
++++++++++++++++
|
|
||||||
|
|
||||||
With this release, the versioning of Gunicorn is changing. Gunicorn is
|
|
||||||
stable since a long time and there is no point to release a "1.0" now.
|
|
||||||
It should have been done since a long time. 0.17 really meant it was the
|
|
||||||
17th stable version. From the beginning we have only 2 kind of
|
|
||||||
releases:
|
|
||||||
|
|
||||||
major release: releases with major changes or huge features added
|
|
||||||
services releases: fixes and minor features added So from now we will
|
|
||||||
apply the following versioning ``<major>.<service>``. For example ``17.5`` is a
|
|
||||||
service release.
|
|
||||||
|
|
||||||
0.17.4 / 2013-04-24
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- fix unix socket address parsing
|
|
||||||
|
|
||||||
0.17.3 / 2013-04-23
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- add systemd sockets support
|
|
||||||
- add ``python -m gunicorn.app.wsgiapp`` support
|
|
||||||
- improve logger class inheritance
|
|
||||||
- exit when the config file isn't found
|
|
||||||
- add the -R option to enable stdio inheritance in daemon mode
|
|
||||||
- don't close file descriptors > 3 in daemon mode
|
|
||||||
- improve STDOUT/STDERR logging
|
|
||||||
- fix pythonpath option
|
|
||||||
- fix pidfile creation on Python 3
|
|
||||||
- fix gevent worker exit
|
|
||||||
- fix ipv6 detection when the platform isn't supporting it
|
|
||||||
|
|
||||||
0.17.2 / 2013-01-07
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- optimize readline
|
|
||||||
- make imports errors more visible when loading an app or a logging
|
|
||||||
class
|
|
||||||
- fix tornado worker: don't pass ssl options if there are none
|
|
||||||
- fix PEP3333: accept only bytetrings in the response body
|
|
||||||
- fix support on CYGWIN platforms
|
|
||||||
|
|
||||||
0.17.1 / 2013-01-05
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- add syslog facility name setting
|
|
||||||
- fix ``--version`` command line argument
|
|
||||||
- fix wsgi url_scheme for https
|
|
||||||
@ -1,228 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2014
|
|
||||||
================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please see :doc:`news` for the latest changes.
|
|
||||||
|
|
||||||
19.1.1 / 2014-08-16
|
|
||||||
===================
|
|
||||||
|
|
||||||
Changes
|
|
||||||
-------
|
|
||||||
|
|
||||||
Core
|
|
||||||
++++
|
|
||||||
|
|
||||||
- fix :issue:`835`: display correct pid of already running instance
|
|
||||||
- fix :pr:`833`: fix `PyTest` class in setup.py.
|
|
||||||
|
|
||||||
|
|
||||||
Logging
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- fix :issue:`838`: statsd logger, send statsd timing metrics in milliseconds
|
|
||||||
- fix :issue:`839`: statsd logger, allows for empty log message while pushing
|
|
||||||
metrics and restore worker number in DEBUG logs
|
|
||||||
- fix :issue:`850`: add timezone to logging
|
|
||||||
- fix :issue:`853`: Respect logger_class setting unless statsd is on
|
|
||||||
|
|
||||||
AioHttp worker
|
|
||||||
++++++++++++++
|
|
||||||
|
|
||||||
- fix :issue:`830` make sure gaiohttp worker is shipped with gunicorn.
|
|
||||||
|
|
||||||
19.1 / 2014-07-26
|
|
||||||
=================
|
|
||||||
|
|
||||||
Changes
|
|
||||||
-------
|
|
||||||
|
|
||||||
Core
|
|
||||||
++++
|
|
||||||
|
|
||||||
- fix :issue:`785`: handle binary type address given to a client socket address
|
|
||||||
- fix graceful shutdown. make sure QUIT and TERMS signals are switched everywhere.
|
|
||||||
- :issue:`799`: fix support loading config from module
|
|
||||||
- :issue:`805`: fix check for file-like objects
|
|
||||||
- fix :issue:`815`: args validation in WSGIApplication.init
|
|
||||||
- fix :issue:`787`: check if we load a pyc file or not.
|
|
||||||
|
|
||||||
|
|
||||||
Tornado worker
|
|
||||||
++++++++++++++
|
|
||||||
|
|
||||||
- fix :issue:`771`: support tornado 4.0
|
|
||||||
- fix :issue:`783`: x_headers error. The x-forwarded-headers option has been removed
|
|
||||||
in `c4873681299212d6082cd9902740eef18c2f14f1
|
|
||||||
<https://github.com/benoitc/gunicorn/commit/c4873681299212d6082cd9902740eef18c2f14f1>`_.
|
|
||||||
The discussion is available on :pr:`633`.
|
|
||||||
|
|
||||||
|
|
||||||
AioHttp worker
|
|
||||||
++++++++++++++
|
|
||||||
|
|
||||||
- fix: fetch all body in input. fix :issue:`803`
|
|
||||||
- fix: don't install the worker if python < 3.3
|
|
||||||
- fix :issue:`822`: Support UNIX sockets in gaiohttp worker
|
|
||||||
|
|
||||||
|
|
||||||
Async worker
|
|
||||||
++++++++++++
|
|
||||||
|
|
||||||
- fix :issue:`790`: StopIteration shouldn't be caught at this level.
|
|
||||||
|
|
||||||
|
|
||||||
Logging
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- add statsd logging handler fix :issue:`748`
|
|
||||||
|
|
||||||
|
|
||||||
Paster
|
|
||||||
++++++
|
|
||||||
|
|
||||||
- fix :issue:`809`: Set global logging configuration from a Paste config.
|
|
||||||
|
|
||||||
|
|
||||||
Extra
|
|
||||||
+++++
|
|
||||||
|
|
||||||
- fix RuntimeError in gunicorn.reloader (:issue:`807`)
|
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- update faq: put a note on how `watch logs in the console
|
|
||||||
<http://docs.gunicorn.org/en/latest/faq.html#why-i-don-t-see-any-logs-in-the-console>`_
|
|
||||||
since many people asked for it.
|
|
||||||
|
|
||||||
|
|
||||||
19.0 / 2014-06-12
|
|
||||||
=================
|
|
||||||
|
|
||||||
Gunicorn 19.0 is a major release with new features and fixes. This
|
|
||||||
version improve a lot the usage of Gunicorn with python 3 by adding `two
|
|
||||||
new workers <http://docs.gunicorn.org/en/latest/design.html#asyncio-workers>`_
|
|
||||||
to it: `gthread` a fully threaded async worker using futures and `gaiohttp` a
|
|
||||||
worker using asyncio.
|
|
||||||
|
|
||||||
|
|
||||||
Breaking Changes
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Switch QUIT and TERM signals
|
|
||||||
++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
With this change, when gunicorn receives a QUIT all the workers are
|
|
||||||
killed immediately and exit and TERM is used for the graceful shutdown.
|
|
||||||
|
|
||||||
Note: the old behaviour was based on the NGINX but the new one is more
|
|
||||||
correct according the following doc:
|
|
||||||
|
|
||||||
https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
|
|
||||||
|
|
||||||
also it is complying with the way the signals are sent by heroku:
|
|
||||||
|
|
||||||
https://devcenter.heroku.com/articles/python-faq#what-constraints-exist-when-developing-applications-on-heroku
|
|
||||||
|
|
||||||
Deprecations
|
|
||||||
++++++++++++
|
|
||||||
|
|
||||||
`run_gunicorn`, `gunicorn_django` and `gunicorn_paster` are now
|
|
||||||
completely deprecated and will be removed in the next release. Use the
|
|
||||||
`gunicorn` command instead.
|
|
||||||
|
|
||||||
|
|
||||||
Changes
|
|
||||||
-------
|
|
||||||
|
|
||||||
core
|
|
||||||
++++
|
|
||||||
|
|
||||||
- add aiohttp worker named `gaiohttp` using asyncio. Full async worker
|
|
||||||
on python 3.
|
|
||||||
- fix HTTP-violating excess whitespace in write_error output
|
|
||||||
- fix: try to log what happened in the worker after a timeout, add a
|
|
||||||
`worker_abort` hook on SIGABRT signal.
|
|
||||||
- fix: save listener socket name in workers so we can handle buffered
|
|
||||||
keep-alive requests after the listener has closed.
|
|
||||||
- add on_exit hook called just before exiting gunicorn.
|
|
||||||
- add support for python 3.4
|
|
||||||
- fix: do not swallow unexpected errors when reaping
|
|
||||||
- fix: remove incompatible SSL option with python 2.6
|
|
||||||
- add new async gthread worker and `--threads` options allows to set multiple
|
|
||||||
threads to listen on connection
|
|
||||||
- deprecate `gunicorn_django` and `gunicorn_paster`
|
|
||||||
- switch QUIT and TERM signal
|
|
||||||
- reap workers in SIGCHLD handler
|
|
||||||
- add universal wheel support
|
|
||||||
- use `email.utils.formatdate` in gunicorn.util.http_date
|
|
||||||
- deprecate the `--debug` option
|
|
||||||
- fix: log exceptions that occur after response start …
|
|
||||||
- allows loading of applications from `.pyc` files (#693)
|
|
||||||
- fix: issue #691, raw_env config file parsing
|
|
||||||
- use a dynamic timeout to wait for the optimal time. (Reduce power
|
|
||||||
usage)
|
|
||||||
- fix python3 support when notifying the arbiter
|
|
||||||
- add: honor $WEB_CONCURRENCY environment variable. Useful for heroku
|
|
||||||
setups.
|
|
||||||
- add: include tz offset in access log
|
|
||||||
- add: include access logs in the syslog handler.
|
|
||||||
- add --reload option for code reloading
|
|
||||||
- add the capability to load `gunicorn.base.Application` without the loading of
|
|
||||||
the arguments of the command line. It allows you to :ref:`embed gunicorn in
|
|
||||||
your own application <custom>`.
|
|
||||||
- improve: set wsgi.multithread to True for async workers
|
|
||||||
- fix logging: make sure to redirect wsgi.errors when needed
|
|
||||||
- add: syslog logging can now be done to a unix socket
|
|
||||||
- fix logging: don't try to redirect stdout/stderr to the logfile.
|
|
||||||
- fix logging: don't propagate log
|
|
||||||
- improve logging: file option can be overridden by the gunicorn options
|
|
||||||
`--error-logfile` and `--access-logfile` if they are given.
|
|
||||||
- fix: don't override SERVER_* by the Host header
|
|
||||||
- fix: handle_error
|
|
||||||
- add more option to configure SSL
|
|
||||||
- fix: sendfile with SSL
|
|
||||||
- add: worker_int callback (to react on SIGTERM)
|
|
||||||
- fix: don't depend on entry point for internal classes, now absolute
|
|
||||||
modules path can be given.
|
|
||||||
- fix: Error messages are now encoded in latin1
|
|
||||||
- fix: request line length check
|
|
||||||
- improvement: proxy_allow_ips: Allow proxy protocol if "*" specified
|
|
||||||
- fix: run worker's `setup` method before setting num_workers
|
|
||||||
- fix: FileWrapper inherit from `object` now
|
|
||||||
- fix: Error messages are now encoded in latin1
|
|
||||||
- fix: don't spam the console on SIGWINCH.
|
|
||||||
- fix: logging -don't stringify T and D logging atoms (#621)
|
|
||||||
- add support for the latest django version
|
|
||||||
- deprecate `run_gunicorn` django option
|
|
||||||
- fix: sys imported twice
|
|
||||||
|
|
||||||
|
|
||||||
gevent worker
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- fix: make sure to stop all listeners
|
|
||||||
- fix: monkey patching is now done in the worker
|
|
||||||
- fix: "global name 'hub' is not defined"
|
|
||||||
- fix: reinit `hub` on old versions of gevent
|
|
||||||
- support gevent 1.0
|
|
||||||
- fix: add subprocess in monkey patching
|
|
||||||
- fix: add support for multiple listener
|
|
||||||
|
|
||||||
|
|
||||||
eventlet worker
|
|
||||||
+++++++++++++++
|
|
||||||
|
|
||||||
- fix: merge duplicate EventletWorker.init_process method (fixes #657)
|
|
||||||
- fix: missing errno import for eventlet sendfile patch
|
|
||||||
- fix: add support for multiple listener
|
|
||||||
|
|
||||||
|
|
||||||
tornado worker
|
|
||||||
++++++++++++++
|
|
||||||
|
|
||||||
- add graceful stop support
|
|
||||||
@ -1,219 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2015
|
|
||||||
================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please see :doc:`news` for the latest changes.
|
|
||||||
|
|
||||||
19.4.3 / 2015/12/30
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix: don't check if a file is writable using os.stat with SELINUX (:issue:`1171`)
|
|
||||||
|
|
||||||
19.4.2 / 2015/12/29
|
|
||||||
===================
|
|
||||||
|
|
||||||
Core
|
|
||||||
++++
|
|
||||||
|
|
||||||
- improvement: handle HaltServer in manage_workers (:issue:`1095`)
|
|
||||||
- fix: Do not rely on sendfile sending requested count (:issue:`1155`)
|
|
||||||
- fix: claridy --no-sendfile default (:issue:`1156`)
|
|
||||||
- fix: LoggingCatch sendfile failure from no file descriptor (:issue:`1160`)
|
|
||||||
|
|
||||||
Logging
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- fix: Always send access log to syslog if syslog is on
|
|
||||||
- fix: check auth before trying to own a file (:issue:`1157`)
|
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- fix: Fix Slowloris broken link. (:issue:`1142`)
|
|
||||||
- Tweak markup in faq.rst
|
|
||||||
|
|
||||||
Testing
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- fix: gaiohttp test (:issue:`1164`)
|
|
||||||
|
|
||||||
19.4.1 / 2015/11/25
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix tornado worker (:issue:`1154`)
|
|
||||||
|
|
||||||
19.4.0 / 2015/11/20
|
|
||||||
===================
|
|
||||||
|
|
||||||
Core
|
|
||||||
++++
|
|
||||||
|
|
||||||
- fix: make sure that a user is able to access to the logs after dropping a
|
|
||||||
privilege (:issue:`1116`)
|
|
||||||
- improvement: inherit the `Exception` class where it needs to be (:issue:`997`)
|
|
||||||
- fix: make sure headers are always encoded as latin1 RFC 2616 (:issue:`1102`)
|
|
||||||
- improvement: reduce arbiter noise (:issue:`1078`)
|
|
||||||
- fix: don't close the unix socket when the worker exit (:issue:`1088`)
|
|
||||||
- improvement: Make last logged worker count an explicit instance var (:issue:`1078`)
|
|
||||||
- improvement: prefix config file with its type (:issue:`836`)
|
|
||||||
- improvement: pidfile handing (:issue:`1042`)
|
|
||||||
- fix: catch OSError as well as ValueError on race condition (:issue:`1052`)
|
|
||||||
- improve support of ipv6 by backporting urlparse.urlsplit from Python 2.7 to
|
|
||||||
Python 2.6.
|
|
||||||
- fix: raise InvalidRequestLine when the line contains malicious data
|
|
||||||
(:issue:`1023`)
|
|
||||||
- fix: fix argument to disable sendfile
|
|
||||||
- fix: add gthread to the list of supported workers (:issue:`1011`)
|
|
||||||
- improvement: retry socket binding up to five times upon EADDRNOTAVAIL
|
|
||||||
(:issue:`1004`)
|
|
||||||
- **breaking change**: only honor headers that can be encoded in ascii to comply to
|
|
||||||
the RFC 7230 (See :issue:`1151`).
|
|
||||||
|
|
||||||
Logging
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- add new parameters to access log (:issue:`1132`)
|
|
||||||
- fix: make sure that files handles are correctly reopened on HUP
|
|
||||||
(:issue:`627`)
|
|
||||||
- include request URL in error message (:issue:`1071`)
|
|
||||||
- get username in access logs (:issue:`1069`)
|
|
||||||
- fix statsd logging support on Python 3 (:issue:`1010`)
|
|
||||||
|
|
||||||
Testing
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- use last version of mock.
|
|
||||||
- many fixes in Travis CI support
|
|
||||||
- miscellaneous improvements in tests
|
|
||||||
|
|
||||||
Thread worker
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- fix: Fix self.nr usage in ThreadedWorker so that auto restart works as
|
|
||||||
expected (:issue:`1031`)
|
|
||||||
|
|
||||||
Gevent worker
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- fix quit signal handling (:issue:`1128`)
|
|
||||||
- add support for Python 3 (:issue:`1066`)
|
|
||||||
- fix: make graceful shutdown thread-safe (:issue:`1032`)
|
|
||||||
|
|
||||||
Tornado worker
|
|
||||||
++++++++++++++
|
|
||||||
|
|
||||||
- fix ssl options (:issue:`1146`, :issue:`1135`)
|
|
||||||
- don't check timeout when stopping gracefully (:issue:`1106`)
|
|
||||||
|
|
||||||
AIOHttp worker
|
|
||||||
++++++++++++++
|
|
||||||
|
|
||||||
- add SSL support (:issue:`1105`)
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- fix link to proc name setting (:issue:`1144`)
|
|
||||||
- fix worker class documentation (:issue:`1141`, :issue:`1104`)
|
|
||||||
- clarify graceful timeout documentation (:issue:`1137`)
|
|
||||||
- don't duplicate NGINX config files examples (:issue:`1050`, :issue:`1048`)
|
|
||||||
- add `web.py` framework example (:issue:`1117`)
|
|
||||||
- update Debian/Ubuntu installations instructions (:issue:`1112`)
|
|
||||||
- clarify `pythonpath` setting description (:issue:`1080`)
|
|
||||||
- tweak some example for python3
|
|
||||||
- clarify `sendfile` documentation
|
|
||||||
- miscellaneous typos in source code comments (thanks!)
|
|
||||||
- clarify why REMOTE_ADD may not be the user's IP address (:issue:`1037`)
|
|
||||||
|
|
||||||
|
|
||||||
Misc
|
|
||||||
++++
|
|
||||||
|
|
||||||
- fix: reloader should survive SyntaxError (:issue:`994`)
|
|
||||||
- fix: expose the reloader class to the worker.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
19.3.0 / 2015/03/06
|
|
||||||
===================
|
|
||||||
|
|
||||||
Core
|
|
||||||
++++
|
|
||||||
|
|
||||||
- fix: :issue:`978` make sure a listener is inheritable
|
|
||||||
- add `check_config` class method to workers
|
|
||||||
- fix: :issue:`983` fix select timeout in sync worker with multiple
|
|
||||||
connections
|
|
||||||
- allows workers to access to the reloader. close :issue:`984`
|
|
||||||
- raise TypeError instead of AssertionError
|
|
||||||
|
|
||||||
Logging
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- make Logger.loglevel a class attribute
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- fix: :issue:`988` fix syntax errors in examples/gunicorn_rc
|
|
||||||
|
|
||||||
|
|
||||||
19.2.1 / 2015/02/4
|
|
||||||
==================
|
|
||||||
|
|
||||||
Logging
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- expose loglevel in the Logger class
|
|
||||||
|
|
||||||
AsyncIO worker (gaiohttp)
|
|
||||||
+++++++++++++++++++++++++
|
|
||||||
|
|
||||||
- fix :issue:`977` fix initial crash
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- document security mailing-list in the contributing page.
|
|
||||||
|
|
||||||
19.2 / 2015/01/30
|
|
||||||
=================
|
|
||||||
|
|
||||||
Core
|
|
||||||
++++
|
|
||||||
|
|
||||||
- optimize the sync workers when listening on a single interface
|
|
||||||
- add `--sendfile` settings to enable/disable sendfile. fix :issue:`856` .
|
|
||||||
- add the selectors module to the code base. :issue:`886`
|
|
||||||
- add `--max-requests-jitter` setting to set the maximum jitter to add to the
|
|
||||||
max-requests setting.
|
|
||||||
- fix :issue:`899` propagate proxy_protocol_info to keep-alive requests
|
|
||||||
- fix :issue:`863` worker timeout: dynamic timeout has been removed
|
|
||||||
- fix: Avoid world writable file
|
|
||||||
|
|
||||||
Logging
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- fix :issue:`941` set logconfig default to paster more trivially
|
|
||||||
- add statsd-prefix config setting: set the prefix to use when emitting statsd
|
|
||||||
metrics
|
|
||||||
- :issue:`832` log to console by default
|
|
||||||
|
|
||||||
Thread Worker
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- fix :issue:`908` make sure the worker can continue to accept requests
|
|
||||||
|
|
||||||
Eventlet Worker
|
|
||||||
+++++++++++++++
|
|
||||||
|
|
||||||
- fix :issue:`867` Fix eventlet shutdown to actively shut down the workers.
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
Many improvements and fixes have been done, see the detailed changelog for
|
|
||||||
more information.
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2016
|
|
||||||
================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please see :doc:`news` for the latest changes
|
|
||||||
|
|
||||||
19.6.0 / 2016/05/21
|
|
||||||
===================
|
|
||||||
|
|
||||||
Core & Logging
|
|
||||||
++++++++++++++
|
|
||||||
|
|
||||||
- improvement of the binary upgrade behaviour using USR2: remove file locking (:issue:`1270`)
|
|
||||||
- add the ``--capture-output`` setting to capture stdout/stderr tot the log
|
|
||||||
file (:issue:`1271`)
|
|
||||||
- Allow disabling ``sendfile()`` via the ``SENDFILE`` environment variable
|
|
||||||
(:issue:`1252`)
|
|
||||||
- fix reload under pycharm (:issue:`1129`)
|
|
||||||
|
|
||||||
Workers
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- fix: make sure to remove the signal from the worker pipe (:issue:`1269`)
|
|
||||||
- fix: **gthread** worker, handle removed socket in the select loop
|
|
||||||
(:issue:`1258`)
|
|
||||||
|
|
||||||
19.5.0 / 2016/05/10
|
|
||||||
===================
|
|
||||||
|
|
||||||
Core
|
|
||||||
++++
|
|
||||||
|
|
||||||
- fix: Ensure response to HEAD request won't have message body
|
|
||||||
- fix: lock domain socket and remove on last arbiter exit (:issue:`1220`)
|
|
||||||
- improvement: use EnvironmentError instead of socket.error (:issue:`939`)
|
|
||||||
- add: new ``FORWARDED_ALLOW_IPS`` environment variable (:issue:`1205`)
|
|
||||||
- fix: infinite recursion when destroying sockets (:issue:`1219`)
|
|
||||||
- fix: close sockets on shutdown (:issue:`922`)
|
|
||||||
- fix: clean up sys.exc_info calls to drop circular refs (:issue:`1228`)
|
|
||||||
- fix: do post_worker_init after load_wsgi (:issue:`1248`)
|
|
||||||
|
|
||||||
Workers
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- fix access logging in gaiohttp worker (:issue:`1193`)
|
|
||||||
- eventlet: handle QUIT in a new coroutine (:issue:`1217`)
|
|
||||||
- gevent: remove obsolete exception clauses in run (:issue:`1218`)
|
|
||||||
- tornado: fix extra "Server" response header (:issue:`1246`)
|
|
||||||
- fix: unblock the wait loop under python 3.5 in sync worker (:issue:`1256`)
|
|
||||||
|
|
||||||
Logging
|
|
||||||
+++++++
|
|
||||||
|
|
||||||
- fix: log message for listener reloading (:issue:`1181`)
|
|
||||||
- Let logging module handle traceback printing (:issue:`1201`)
|
|
||||||
- improvement: Allow configuring logger_class with statsd_host (:issue:`1188`)
|
|
||||||
- fix: traceback formatting (:issue:`1235`)
|
|
||||||
- fix: print error logs on stderr and access logs on stdout (:issue:`1184`)
|
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
+++++++++++++
|
|
||||||
|
|
||||||
- Simplify installation instructions in gunicorn.org (:issue:`1072`)
|
|
||||||
- Fix URL and default worker type in example_config (:issue:`1209`)
|
|
||||||
- update django doc url to 1.8 lts (:issue:`1213`)
|
|
||||||
- fix: miscellaneous wording corrections (:issue:`1216`)
|
|
||||||
- Add PSF License Agreement of selectors.py to NOTICE (:issue: `1226`)
|
|
||||||
- document LOGGING overriding (:issue:`1051`)
|
|
||||||
- put a note that error logs are only errors from Gunicorn (:issue:`1124`)
|
|
||||||
- add a note about the requirements of the threads workers under python 2.x (:issue:`1200`)
|
|
||||||
- add access_log_format to config example (:issue:`1251`)
|
|
||||||
|
|
||||||
Tests
|
|
||||||
+++++
|
|
||||||
|
|
||||||
- Use more pytest.raises() in test_http.py
|
|
||||||
|
|
||||||
|
|
||||||
19.4.5 / 2016/01/05
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix: NameError fileno in gunicorn.http.wsgi (:issue:`1178`)
|
|
||||||
|
|
||||||
19.4.4 / 2016/01/04
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix: check if a fileobject can be used with sendfile(2) (:issue:`1174`)
|
|
||||||
- doc: be more descriptive in errorlog option (:issue:`1173`)
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2017
|
|
||||||
================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please see :doc:`news` for the latest changes
|
|
||||||
|
|
||||||
19.7.1 / 2017/03/21
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix: continue if SO_REUSEPORT seems to be available but fails (:issue:`1480`)
|
|
||||||
- fix: support non-decimal values for the umask command line option (:issue:`1325`)
|
|
||||||
|
|
||||||
19.7.0 / 2017/03/01
|
|
||||||
===================
|
|
||||||
|
|
||||||
- The previously deprecated ``gunicorn_django`` command has been removed.
|
|
||||||
Use the :ref:`gunicorn-cmd` command-line interface instead.
|
|
||||||
- The previously deprecated ``django_settings`` setting has been removed.
|
|
||||||
Use the :ref:`raw-env` setting instead.
|
|
||||||
- The default value of :ref:`ssl-version` has been changed from
|
|
||||||
``ssl.PROTOCOL_TLSv1`` to ``ssl.PROTOCOL_SSLv23``.
|
|
||||||
- fix: initialize the group access list when initgroups is set (:issue:`1297`)
|
|
||||||
- add environment variables to gunicorn access log format (:issue:`1291`)
|
|
||||||
- add --paste-global-conf option (:issue:`1304`)
|
|
||||||
- fix: print access logs to STDOUT (:issue:`1184`)
|
|
||||||
- remove upper limit on max header size config (:issue:`1313`)
|
|
||||||
- fix: print original exception on AppImportError (:issue:`1334`)
|
|
||||||
- use SO_REUSEPORT if available (:issue:`1344`)
|
|
||||||
- `fix leak <https://github.com/benoitc/gunicorn/commit/b4c41481e2d5ef127199a4601417a6819053c3fd>`_ of duplicate file descriptor for bound sockets.
|
|
||||||
- add --reload-engine option, support inotify and other backends (:issue:`1368`, :issue:`1459`)
|
|
||||||
- fix: reject request with invalid HTTP versions
|
|
||||||
- add ``child_exit`` callback (:issue:`1394`)
|
|
||||||
- add support for eventlets _AlreadyHandled object (:issue:`1406`)
|
|
||||||
- format boot tracebacks properly with reloader (:issue:`1408`)
|
|
||||||
- refactor socket activation and fd inheritance for better support of SystemD (:issue:`1310`)
|
|
||||||
- fix: o fds are given by default in gunicorn (:issue:`1423`)
|
|
||||||
- add ability to pass settings to GUNICORN_CMD_ARGS environment variable which helps in container world (:issue:`1385`)
|
|
||||||
- fix: catch access denied to pid file (:issue:`1091`)
|
|
||||||
- many additions and improvements to the documentation
|
|
||||||
|
|
||||||
Breaking Change
|
|
||||||
+++++++++++++++
|
|
||||||
|
|
||||||
- **Python 2.6.0** is the last supported version
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2018
|
|
||||||
================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please see :doc:`news` for the latest changes
|
|
||||||
|
|
||||||
19.9.0 / 2018/07/03
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix: address a regression that prevented syslog support from working
|
|
||||||
(:issue:`1668`, :pr:`1773`)
|
|
||||||
- fix: correctly set `REMOTE_ADDR` on versions of Python 3 affected by
|
|
||||||
`Python Issue 30205 <https://bugs.python.org/issue30205>`_
|
|
||||||
(:issue:`1755`, :pr:`1796`)
|
|
||||||
- fix: show zero response length correctly in access log (:pr:`1787`)
|
|
||||||
- fix: prevent raising :exc:`AttributeError` when ``--reload`` is not passed
|
|
||||||
in case of a :exc:`SyntaxError` raised from the WSGI application.
|
|
||||||
(:issue:`1805`, :pr:`1806`)
|
|
||||||
- The internal module ``gunicorn.workers.async`` was renamed to ``gunicorn.workers.base_async``
|
|
||||||
since ``async`` is now a reserved word in Python 3.7.
|
|
||||||
(:pr:`1527`)
|
|
||||||
|
|
||||||
19.8.1 / 2018/04/30
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix: secure scheme headers when bound to a unix socket
|
|
||||||
(:issue:`1766`, :pr:`1767`)
|
|
||||||
|
|
||||||
19.8.0 / 2018/04/28
|
|
||||||
===================
|
|
||||||
|
|
||||||
- Eventlet 0.21.0 support (:issue:`1584`)
|
|
||||||
- Tornado 5 support (:issue:`1728`, :pr:`1752`)
|
|
||||||
- support watching additional files with ``--reload-extra-file``
|
|
||||||
(:pr:`1527`)
|
|
||||||
- support configuring logging with a dictionary with ``--logging-config-dict``
|
|
||||||
(:issue:`1087`, :pr:`1110`, :pr:`1602`)
|
|
||||||
- add support for the ``--config`` flag in the ``GUNICORN_CMD_ARGS`` environment
|
|
||||||
variable (:issue:`1576`, :pr:`1581`)
|
|
||||||
- disable ``SO_REUSEPORT`` by default and add the ``--reuse-port`` setting
|
|
||||||
(:issue:`1553`, :issue:`1603`, :pr:`1669`)
|
|
||||||
- fix: installing `inotify` on MacOS no longer breaks the reloader
|
|
||||||
(:issue:`1540`, :pr:`1541`)
|
|
||||||
- fix: do not throw ``TypeError`` when ``SO_REUSEPORT`` is not available
|
|
||||||
(:issue:`1501`, :pr:`1491`)
|
|
||||||
- fix: properly decode HTTP paths containing certain non-ASCII characters
|
|
||||||
(:issue:`1577`, :pr:`1578`)
|
|
||||||
- fix: remove whitespace when logging header values under gevent (:pr:`1607`)
|
|
||||||
- fix: close unlinked temporary files (:issue:`1327`, :pr:`1428`)
|
|
||||||
- fix: parse ``--umask=0`` correctly (:issue:`1622`, :pr:`1632`)
|
|
||||||
- fix: allow loading applications using relative file paths
|
|
||||||
(:issue:`1349`, :pr:`1481`)
|
|
||||||
- fix: force blocking mode on the gevent sockets (:issue:`880`, :pr:`1616`)
|
|
||||||
- fix: preserve leading `/` in request path (:issue:`1512`, :pr:`1511`)
|
|
||||||
- fix: forbid contradictory secure scheme headers
|
|
||||||
- fix: handle malformed basic authentication headers in access log
|
|
||||||
(:issue:`1683`, :pr:`1684`)
|
|
||||||
- fix: defer handling of ``USR1`` signal to a new greenlet under gevent
|
|
||||||
(:issue:`1645`, :pr:`1651`)
|
|
||||||
- fix: the threaded worker would sometimes close the wrong keep-alive
|
|
||||||
connection under Python 2 (:issue:`1698`, :pr:`1699`)
|
|
||||||
- fix: re-open log files on ``USR1`` signal using ``handler._open`` to
|
|
||||||
support subclasses of ``FileHandler`` (:issue:`1739`, :pr:`1742`)
|
|
||||||
- deprecation: the ``gaiohttp`` worker is deprecated, see the
|
|
||||||
:ref:`worker-class` documentation for more information
|
|
||||||
(:issue:`1338`, :pr:`1418`, :pr:`1569`)
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2019
|
|
||||||
================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please see :doc:`news` for the latest changes
|
|
||||||
|
|
||||||
20.0.4 / 2019/11/26
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix binding a socket using the file descriptor
|
|
||||||
- remove support for the `bdist_rpm` build
|
|
||||||
|
|
||||||
20.0.3 / 2019/11/24
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fixed load of a config file without a Python extension
|
|
||||||
- fixed `socketfromfd.fromfd` when defaults are not set
|
|
||||||
|
|
||||||
.. note:: we now warn when we load a config file without Python Extension
|
|
||||||
|
|
||||||
20.0.2 / 2019/11/23
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix changelog
|
|
||||||
|
|
||||||
20.0.1 / 2019/11/23
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fixed the way the config module is loaded. `__file__` is now available
|
|
||||||
- fixed `wsgi.input_terminated`. It is always true.
|
|
||||||
- use the highest protocol version of openssl by default
|
|
||||||
- only support Python >= 3.5
|
|
||||||
- added `__repr__` method to `Config` instance
|
|
||||||
- fixed support of AIX platform and musl libc in `socketfromfd.fromfd` function
|
|
||||||
- fixed support of applications loaded from a factory function
|
|
||||||
- fixed chunked encoding support to prevent any `request smuggling <https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn>`_
|
|
||||||
- Capture os.sendfile before patching in gevent and eventlet workers.
|
|
||||||
fix `RecursionError`.
|
|
||||||
- removed locking in reloader when adding new files
|
|
||||||
- load the WSGI application before the loader to pick up all files
|
|
||||||
|
|
||||||
.. note:: this release add official support for applications loaded from a factory function
|
|
||||||
as documented in Flask and other places.
|
|
||||||
|
|
||||||
|
|
||||||
19.10.0 / 2019/11/23
|
|
||||||
====================
|
|
||||||
|
|
||||||
- unblock select loop during reload of a sync worker
|
|
||||||
- security fix: http desync attack
|
|
||||||
- handle `wsgi.input_terminated`
|
|
||||||
- added support for str and bytes in unix socket addresses
|
|
||||||
- fixed `max_requests` setting
|
|
||||||
- headers values are now encoded as LATN1, not ASCII
|
|
||||||
- fixed `InotifyReloadeder`: handle `module.__file__` is None
|
|
||||||
- fixed compatibility with tornado 6
|
|
||||||
- fixed root logging
|
|
||||||
- Prevent removalof unix sockets from `reuse_port`
|
|
||||||
- Clear tornado ioloop before os.fork
|
|
||||||
- Miscellaneous fixes and improvement for linting using Pylint
|
|
||||||
|
|
||||||
20.0 / 2019/10/30
|
|
||||||
=================
|
|
||||||
|
|
||||||
- Fixed `fdopen` `RuntimeWarning` in Python 3.8
|
|
||||||
- Added check and exception for str type on value in Response process_headers method.
|
|
||||||
- Ensure WSGI header value is string before conducting regex search on it.
|
|
||||||
- Added pypy3 to list of tested environments
|
|
||||||
- Grouped `StopIteration` and `KeyboardInterrupt` exceptions with same body together in Arbiter.run()
|
|
||||||
- Added `setproctitle` module to `extras_require` in setup.py
|
|
||||||
- Avoid unnecessary chown of temporary files
|
|
||||||
- Logging: Handle auth type case insensitively
|
|
||||||
- Removed `util.import_module`
|
|
||||||
- Removed fallback for `types.SimpleNamespace` in tests utils
|
|
||||||
- Use `SourceFileLoader` instead instead of `execfile_`
|
|
||||||
- Use `importlib` instead of `__import__` and eval`
|
|
||||||
- Fixed eventlet patching
|
|
||||||
- Added optional `datadog <https://www.datadoghq.com>`_ tags for statsd metrics
|
|
||||||
- Header values now are encoded using latin-1, not ascii.
|
|
||||||
- Rewritten `parse_address` util added test
|
|
||||||
- Removed redundant super() arguments
|
|
||||||
- Simplify `futures` import in gthread module
|
|
||||||
- Fixed worker_connections` setting to also affects the Gthread worker type
|
|
||||||
- Fixed setting max_requests
|
|
||||||
- Bump minimum Eventlet and Gevent versions to 0.24 and 1.4
|
|
||||||
- Use Python default SSL cipher list by default
|
|
||||||
- handle `wsgi.input_terminated` extension
|
|
||||||
- Simplify Paste Deployment documentation
|
|
||||||
- Fix root logging: root and logger are same level.
|
|
||||||
- Fixed typo in ssl_version documentation
|
|
||||||
- Documented systemd deployment unit examples
|
|
||||||
- Added systemd sd_notify support
|
|
||||||
- Fixed typo in gthread.py
|
|
||||||
- Added `tornado <https://www.tornadoweb.org/>`_ 5 and 6 support
|
|
||||||
- Declare our setuptools dependency
|
|
||||||
- Added support to `--bind` to open file descriptors
|
|
||||||
- Document how to serve WSGI app modules from Gunicorn
|
|
||||||
- Provide guidance on X-Forwarded-For access log in documentation
|
|
||||||
- Add support for named constants in the `--ssl-version` flag
|
|
||||||
- Clarify log format usage of header & environment in documentation
|
|
||||||
- Fixed systemd documentation to properly setup gunicorn unix socket
|
|
||||||
- Prevent removal unix socket for reuse_port
|
|
||||||
- Fix `ResourceWarning` when reading a Python config module
|
|
||||||
- Remove unnecessary call to dict keys method
|
|
||||||
- Support str and bytes for UNIX socket addresses
|
|
||||||
- fixed `InotifyReloadeder`: handle `module.__file__` is None
|
|
||||||
- `/dev/shm` as a convenient alternative to making your own tmpfs mount in fchmod FAQ
|
|
||||||
- fix examples to work on python3
|
|
||||||
- Fix typo in `--max-requests` documentation
|
|
||||||
- Clear tornado ioloop before os.fork
|
|
||||||
- Miscellaneous fixes and improvement for linting using Pylint
|
|
||||||
|
|
||||||
Breaking Change
|
|
||||||
+++++++++++++++
|
|
||||||
|
|
||||||
- Removed gaiohttp worker
|
|
||||||
- Drop support for Python 2.x
|
|
||||||
- Drop support for EOL Python 3.2 and 3.3
|
|
||||||
- Drop support for Paste Deploy server blocks
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2020
|
|
||||||
================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please see :doc:`news` for the latest changes
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2021
|
|
||||||
================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please see :doc:`news` for the latest changes
|
|
||||||
|
|
||||||
20.1.0 - 2021-02-12
|
|
||||||
===================
|
|
||||||
|
|
||||||
- document WEB_CONCURRENCY is set by, at least, Heroku
|
|
||||||
- capture peername from accept: Avoid calls to getpeername by capturing the peer name returned by
|
|
||||||
accept
|
|
||||||
- log a warning when a worker was terminated due to a signal
|
|
||||||
- fix tornado usage with latest versions of Django
|
|
||||||
- add support for python -m gunicorn
|
|
||||||
- fix systemd socket activation example
|
|
||||||
- allows to set wsgi application in config file using `wsgi_app`
|
|
||||||
- document `--timeout = 0`
|
|
||||||
- always close a connection when the number of requests exceeds the max requests
|
|
||||||
- Disable keepalive during graceful shutdown
|
|
||||||
- kill tasks in the gthread workers during upgrade
|
|
||||||
- fix latency in gevent worker when accepting new requests
|
|
||||||
- fix file watcher: handle errors when new worker reboot and ensure the list of files is kept
|
|
||||||
- document the default name and path of the configuration file
|
|
||||||
- document how variable impact configuration
|
|
||||||
- document the `$PORT` environment variable
|
|
||||||
- added milliseconds option to request_time in access_log
|
|
||||||
- added PIP requirements to be used for example
|
|
||||||
- remove version from the Server header
|
|
||||||
- fix sendfile: use `socket.sendfile` instead of `os.sendfile`
|
|
||||||
- reloader: use absolute path to prevent empty to prevent0 `InotifyError` when a file
|
|
||||||
is added to the working directory
|
|
||||||
- Add --print-config option to print the resolved settings at startup.
|
|
||||||
- remove the `--log-dict-config` CLI flag because it never had a working format
|
|
||||||
(the `logconfig_dict` setting in configuration files continues to work)
|
|
||||||
|
|
||||||
|
|
||||||
** Breaking changes **
|
|
||||||
|
|
||||||
- minimum version is Python 3.5
|
|
||||||
- remove version from the Server header
|
|
||||||
|
|
||||||
** Documentation **
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
** Others **
|
|
||||||
|
|
||||||
- miscellaneous changes in the code base to be a better citizen with Python 3
|
|
||||||
- remove dead code
|
|
||||||
- fix documentation generation
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2023
|
|
||||||
================
|
|
||||||
|
|
||||||
21.2.0 - 2023-07-19
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix thread worker: revert change considering connection as idle .
|
|
||||||
|
|
||||||
*** NOTE ***
|
|
||||||
|
|
||||||
This is fixing the bad file description error.
|
|
||||||
|
|
||||||
21.1.0 - 2023-07-18
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix thread worker: fix socket removal from the queue
|
|
||||||
|
|
||||||
21.0.1 - 2023-07-17
|
|
||||||
===================
|
|
||||||
|
|
||||||
- fix documentation build
|
|
||||||
|
|
||||||
21.0.0 - 2023-07-17
|
|
||||||
===================
|
|
||||||
|
|
||||||
- support python 3.11
|
|
||||||
- fix gevent and eventlet workers
|
|
||||||
- fix threads support (gththread): improve performance and unblock requests
|
|
||||||
- SSL: now use SSLContext object
|
|
||||||
- HTTP parser: miscellaneous fixes
|
|
||||||
- remove unnecessary setuid calls
|
|
||||||
- fix testing
|
|
||||||
- improve logging
|
|
||||||
- miscellaneous fixes to core engine
|
|
||||||
|
|
||||||
*** RELEASE NOTE ***
|
|
||||||
|
|
||||||
We made this release major to start our new release cycle. More info will be provided on our discussion forum.
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
================
|
|
||||||
Changelog - 2024
|
|
||||||
================
|
|
||||||
|
|
||||||
23.0.0 - 2024-08-10
|
|
||||||
===================
|
|
||||||
|
|
||||||
- minor docs fixes (:pr:`3217`, :pr:`3089`, :pr:`3167`)
|
|
||||||
- worker_class parameter accepts a class (:pr:`3079`)
|
|
||||||
- fix deadlock if request terminated during chunked parsing (:pr:`2688`)
|
|
||||||
- permit receiving Transfer-Encodings: compress, deflate, gzip (:pr:`3261`)
|
|
||||||
- permit Transfer-Encoding headers specifying multiple encodings. note: no parameters, still (:pr:`3261`)
|
|
||||||
- sdist generation now explicitly excludes sphinx build folder (:pr:`3257`)
|
|
||||||
- decode bytes-typed status (as can be passed by gevent) as utf-8 instead of raising `TypeError` (:pr:`2336`)
|
|
||||||
- raise correct Exception when encounting invalid chunked requests (:pr:`3258`)
|
|
||||||
- the SCRIPT_NAME and PATH_INFO headers, when received from allowed forwarders, are no longer restricted for containing an underscore (:pr:`3192`)
|
|
||||||
- include IPv6 loopback address ``[::1]`` in default for :ref:`forwarded-allow-ips` and :ref:`proxy-allow-ips` (:pr:`3192`)
|
|
||||||
|
|
||||||
** NOTE **
|
|
||||||
|
|
||||||
- The SCRIPT_NAME change mitigates a regression that appeared first in the 22.0.0 release
|
|
||||||
- Review your :ref:`forwarded-allow-ips` setting if you are still not seeing the SCRIPT_NAME transmitted
|
|
||||||
- Review your :ref:`forwarder-headers` setting if you are missing headers after upgrading from a version prior to 22.0.0
|
|
||||||
|
|
||||||
** Breaking changes **
|
|
||||||
|
|
||||||
- refuse requests where the uri field is empty (:pr:`3255`)
|
|
||||||
- refuse requests with invalid CR/LR/NUL in heade field values (:pr:`3253`)
|
|
||||||
- remove temporary ``--tolerate-dangerous-framing`` switch from 22.0 (:pr:`3260`)
|
|
||||||
- If any of the breaking changes affect you, be aware that now refused requests can post a security problem, especially so in setups involving request pipe-lining and/or proxies.
|
|
||||||
|
|
||||||
22.0.0 - 2024-04-17
|
|
||||||
===================
|
|
||||||
|
|
||||||
- use `utime` to notify workers liveness
|
|
||||||
- migrate setup to pyproject.toml
|
|
||||||
- fix numerous security vulnerabilities in HTTP parser (closing some request smuggling vectors)
|
|
||||||
- parsing additional requests is no longer attempted past unsupported request framing
|
|
||||||
- on HTTP versions < 1.1 support for chunked transfer is refused (only used in exploits)
|
|
||||||
- requests conflicting configured or passed SCRIPT_NAME now produce a verbose error
|
|
||||||
- Trailer fields are no longer inspected for headers indicating secure scheme
|
|
||||||
- support Python 3.12
|
|
||||||
|
|
||||||
** Breaking changes **
|
|
||||||
|
|
||||||
- minimum version is Python 3.7
|
|
||||||
- the limitations on valid characters in the HTTP method have been bounded to Internet Standards
|
|
||||||
- requests specifying unsupported transfer coding (order) are refused by default (rare)
|
|
||||||
- HTTP methods are no longer casefolded by default (IANA method registry contains none affected)
|
|
||||||
- HTTP methods containing the number sign (#) are no longer accepted by default (rare)
|
|
||||||
- HTTP versions < 1.0 or >= 2.0 are no longer accepted by default (rare, only HTTP/1.1 is supported)
|
|
||||||
- HTTP versions consisting of multiple digits or containing a prefix/suffix are no longer accepted
|
|
||||||
- HTTP header field names Gunicorn cannot safely map to variables are silently dropped, as in other software
|
|
||||||
- HTTP headers with empty field name are refused by default (no legitimate use cases, used in exploits)
|
|
||||||
- requests with both Transfer-Encoding and Content-Length are refused by default (such a message might indicate an attempt to perform request smuggling)
|
|
||||||
- empty transfer codings are no longer permitted (reportedly seen with really old & broken proxies)
|
|
||||||
|
|
||||||
|
|
||||||
** SECURITY **
|
|
||||||
|
|
||||||
- fix CVE-2024-1135
|
|
||||||
|
Before Width: | Height: | Size: 14 KiB |
@ -1,37 +0,0 @@
|
|||||||
=========
|
|
||||||
Community
|
|
||||||
=========
|
|
||||||
|
|
||||||
Use these channels to communicate about the project:
|
|
||||||
|
|
||||||
Project Management & Discussions
|
|
||||||
================================
|
|
||||||
|
|
||||||
Project maintenance guidelines are available on the `wiki <https://github.com/benoitc/gunicorn/wiki/Project-management>`_
|
|
||||||
|
|
||||||
GitHub issues are used for 3 different purposes:
|
|
||||||
|
|
||||||
* `Bug tracker <https://github.com/benoitc/gunicorn/issues>`_ : To check for latest bugs. Tip: See existing issues before opening a new one!
|
|
||||||
* `Forum <https://github.com/benoitc/gunicorn/discussions>`_ : Stackoverflow-style questions about Gunicorn usage.
|
|
||||||
* `Other Issues <https://github.com/benoitc/gunicorn/issues>`_ : Discussion of Gunicorn development, new features
|
|
||||||
and project management.
|
|
||||||
|
|
||||||
IRC
|
|
||||||
===
|
|
||||||
|
|
||||||
The Gunicorn channel is on the `Libera Chat <https://libera.chat/>`_ IRC
|
|
||||||
network. You can chat with others on `#gunicorn channel
|
|
||||||
<https://web.libera.chat/?channels=#gunicorn>`_
|
|
||||||
|
|
||||||
Issue Tracking
|
|
||||||
==============
|
|
||||||
|
|
||||||
Bug reports, enhancement requests and tasks generally go in the `Github
|
|
||||||
issue tracker <http://github.com/benoitc/gunicorn/issues>`_
|
|
||||||
|
|
||||||
Security Issues
|
|
||||||
===============
|
|
||||||
|
|
||||||
The security mailing list is a place to report security issues. Only
|
|
||||||
developers are subscribed to it. To post a message to the list use the address
|
|
||||||
to `security@gunicorn.org <mailto:security@gunicorn.org>`_
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
#
|
|
||||||
# Gunicorn documentation build configuration file
|
|
||||||
#
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
DOCS_DIR = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
|
|
||||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
|
||||||
|
|
||||||
# for gunicorn_ext.py
|
|
||||||
sys.path.append(os.path.join(DOCS_DIR, os.pardir))
|
|
||||||
sys.path.insert(0, os.path.join(DOCS_DIR, os.pardir, os.pardir))
|
|
||||||
|
|
||||||
extensions = ['gunicorn_ext']
|
|
||||||
templates_path = ['_templates']
|
|
||||||
source_suffix = '.rst'
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
# General information about the project.
|
|
||||||
project = 'Gunicorn'
|
|
||||||
copyright = '2009-%s, Benoit Chesneau' % time.strftime('%Y')
|
|
||||||
# gunicorn version
|
|
||||||
import gunicorn
|
|
||||||
release = version = gunicorn.__version__
|
|
||||||
|
|
||||||
exclude_patterns = []
|
|
||||||
pygments_style = 'sphinx'
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output ---------------------------------------------------
|
|
||||||
|
|
||||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
|
||||||
try:
|
|
||||||
import sphinx_rtd_theme
|
|
||||||
except ImportError:
|
|
||||||
html_theme = 'default'
|
|
||||||
else:
|
|
||||||
html_theme = 'sphinx_rtd_theme'
|
|
||||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
|
||||||
else:
|
|
||||||
html_theme = 'default'
|
|
||||||
|
|
||||||
html_static_path = ['_static']
|
|
||||||
htmlhelp_basename = 'Gunicorndoc'
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for LaTeX output --------------------------------------------------
|
|
||||||
|
|
||||||
latex_elements = {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
latex_documents = [
|
|
||||||
('index', 'Gunicorn.tex', 'Gunicorn Documentation',
|
|
||||||
'Benoit Chesneau', 'manual'),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output --------------------------------------------
|
|
||||||
man_pages = [
|
|
||||||
('index', 'gunicorn', 'Gunicorn Documentation',
|
|
||||||
['Benoit Chesneau'], 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
texinfo_documents = [
|
|
||||||
('index', 'Gunicorn', 'Gunicorn Documentation',
|
|
||||||
'Benoit Chesneau', 'Gunicorn', 'One line description of project.',
|
|
||||||
'Miscellaneous'),
|
|
||||||
]
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
.. _configuration:
|
|
||||||
|
|
||||||
======================
|
|
||||||
Configuration Overview
|
|
||||||
======================
|
|
||||||
|
|
||||||
Gunicorn reads configuration information from five places.
|
|
||||||
|
|
||||||
Gunicorn first reads environment variables for some configuration
|
|
||||||
:ref:`settings <settings>`.
|
|
||||||
|
|
||||||
Gunicorn then reads configuration from a framework specific configuration
|
|
||||||
file. Currently this only affects Paster applications.
|
|
||||||
|
|
||||||
The third source of configuration information is an optional configuration file
|
|
||||||
``gunicorn.conf.py`` searched in the current working directory or specified
|
|
||||||
using a command line argument. Anything specified in this configuration file
|
|
||||||
will override any framework specific settings.
|
|
||||||
|
|
||||||
The fourth place of configuration information are command line arguments
|
|
||||||
stored in an environment variable named ``GUNICORN_CMD_ARGS``.
|
|
||||||
|
|
||||||
Lastly, the command line arguments used to invoke Gunicorn are the final place
|
|
||||||
considered for configuration settings. If an option is specified on the command
|
|
||||||
line, this is the value that will be used.
|
|
||||||
|
|
||||||
When a configuration file is specified in the command line arguments and in the
|
|
||||||
``GUNICORN_CMD_ARGS`` environment variable, only the configuration
|
|
||||||
file specified on the command line is used.
|
|
||||||
|
|
||||||
Once again, in order of least to most authoritative:
|
|
||||||
1. Environment Variables
|
|
||||||
2. Framework Settings
|
|
||||||
3. Configuration File
|
|
||||||
4. ``GUNICORN_CMD_ARGS``
|
|
||||||
5. Command Line
|
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
To print your resolved configuration when using the command line or the
|
|
||||||
configuration file you can run the following command::
|
|
||||||
|
|
||||||
$ gunicorn --print-config APP_MODULE
|
|
||||||
|
|
||||||
To check your resolved configuration when using the command line or the
|
|
||||||
configuration file you can run the following command::
|
|
||||||
|
|
||||||
$ gunicorn --check-config APP_MODULE
|
|
||||||
|
|
||||||
It also allows you to know if your application can be launched.
|
|
||||||
|
|
||||||
|
|
||||||
Command Line
|
|
||||||
============
|
|
||||||
|
|
||||||
If an option is specified on the command line, it overrides all other values
|
|
||||||
that may have been specified in the app specific settings, or in the optional
|
|
||||||
configuration file. Not all Gunicorn settings are available to be set from the
|
|
||||||
command line. To see the full list of command line settings you can do the
|
|
||||||
usual::
|
|
||||||
|
|
||||||
$ gunicorn -h
|
|
||||||
|
|
||||||
There is also a ``--version`` flag available to the command line scripts that
|
|
||||||
isn't mentioned in the list of :ref:`settings <settings>`.
|
|
||||||
|
|
||||||
.. _configuration_file:
|
|
||||||
|
|
||||||
Configuration File
|
|
||||||
==================
|
|
||||||
|
|
||||||
The configuration file should be a valid Python source file with a **python
|
|
||||||
extension** (e.g. `gunicorn.conf.py`). It only needs to be readable from the
|
|
||||||
file system. More specifically, it does not have to be on the module path
|
|
||||||
(sys.path, PYTHONPATH). Any Python is valid. Just consider that this will be
|
|
||||||
run every time you start Gunicorn (including when you signal Gunicorn to reload).
|
|
||||||
|
|
||||||
To set a parameter, just assign to it. There's no special syntax. The values
|
|
||||||
you provide will be used for the configuration values.
|
|
||||||
|
|
||||||
For instance::
|
|
||||||
|
|
||||||
import multiprocessing
|
|
||||||
|
|
||||||
bind = "127.0.0.1:8000"
|
|
||||||
workers = multiprocessing.cpu_count() * 2 + 1
|
|
||||||
|
|
||||||
All the settings are mentioned in the :ref:`settings <settings>` list.
|
|
||||||
|
|
||||||
|
|
||||||
Framework Settings
|
|
||||||
==================
|
|
||||||
|
|
||||||
Currently, only Paster applications have access to framework specific
|
|
||||||
settings. If you have ideas for providing settings to WSGI applications or
|
|
||||||
pulling information from Django's settings.py feel free to open an issue_ to
|
|
||||||
let us know.
|
|
||||||
|
|
||||||
.. _issue: https://github.com/benoitc/gunicorn/issues
|
|
||||||
|
|
||||||
Paster Applications
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
In your INI file, you can specify to use Gunicorn as the server like such:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[server:main]
|
|
||||||
use = egg:gunicorn#main
|
|
||||||
host = 192.168.0.1
|
|
||||||
port = 80
|
|
||||||
workers = 2
|
|
||||||
proc_name = brim
|
|
||||||
|
|
||||||
Any parameters that Gunicorn knows about will automatically be inserted into
|
|
||||||
the base configuration. Remember that these will be overridden by the config
|
|
||||||
file and/or the command line.
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
.. _custom:
|
|
||||||
|
|
||||||
==================
|
|
||||||
Custom Application
|
|
||||||
==================
|
|
||||||
|
|
||||||
.. versionadded:: 19.0
|
|
||||||
|
|
||||||
Sometimes, you want to integrate Gunicorn with your WSGI application. In this
|
|
||||||
case, you can inherit from :class:`gunicorn.app.base.BaseApplication`.
|
|
||||||
|
|
||||||
Here is a small example where we create a very small WSGI app and load it with
|
|
||||||
a custom Application:
|
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/standalone_app.py
|
|
||||||
:start-after: # See the NOTICE for more information
|
|
||||||
:lines: 2-
|
|
||||||
|
|
||||||
Using server hooks
|
|
||||||
------------------
|
|
||||||
|
|
||||||
If you wish to include server hooks in your custom application, you can specify a function in the config options. Here is an example with the `pre_fork` hook:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def pre_fork(server, worker):
|
|
||||||
print(f"pre-fork server {server} worker {worker}", file=sys.stderr)
|
|
||||||
|
|
||||||
# ...
|
|
||||||
if __name__ == '__main__':
|
|
||||||
options = {
|
|
||||||
'bind': '%s:%s' % ('127.0.0.1', '8080'),
|
|
||||||
'workers': number_of_workers(),
|
|
||||||
'pre_fork': pre_fork,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Direct Usage of Existing WSGI Apps
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
If necessary, you can run Gunicorn straight from Python, allowing you to
|
|
||||||
specify a WSGI-compatible application at runtime. This can be handy for
|
|
||||||
rolling deploys or in the case of using PEX files to deploy your application,
|
|
||||||
as the app and Gunicorn can be bundled in the same PEX file. Gunicorn has
|
|
||||||
this functionality built-in as a first class citizen known as
|
|
||||||
:class:`gunicorn.app.wsgiapp`. This can be used to run WSGI-compatible app
|
|
||||||
instances such as those produced by Flask or Django. Assuming your WSGI API
|
|
||||||
package is *exampleapi*, and your application instance is *app*, this is all
|
|
||||||
you need to get going::
|
|
||||||
|
|
||||||
gunicorn.app.wsgiapp exampleapi:app
|
|
||||||
|
|
||||||
This command will work with any Gunicorn CLI parameters or a config file - just
|
|
||||||
pass them along as if you're directly giving them to Gunicorn:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
# Custom parameters
|
|
||||||
$ python gunicorn.app.wsgiapp exampleapi:app --bind=0.0.0.0:8081 --workers=4
|
|
||||||
# Using a config file
|
|
||||||
$ python gunicorn.app.wsgiapp exampleapi:app -c config.py
|
|
||||||
|
|
||||||
Note for those using PEX: use ``-c gunicorn`` as your entry at build
|
|
||||||
time, and your compiled app should work with the entry point passed to it at
|
|
||||||
run time.
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
# Generic pex build command via bash from root of exampleapi project
|
|
||||||
$ pex . -v -c gunicorn -o compiledapp.pex
|
|
||||||
# Running it
|
|
||||||
./compiledapp.pex exampleapi:app -c gunicorn_config.py
|
|
||||||
@ -1,380 +0,0 @@
|
|||||||
==================
|
|
||||||
Deploying Gunicorn
|
|
||||||
==================
|
|
||||||
|
|
||||||
We strongly recommend using Gunicorn behind a proxy server.
|
|
||||||
|
|
||||||
Nginx Configuration
|
|
||||||
===================
|
|
||||||
|
|
||||||
Although there are many HTTP proxies available, we strongly advise that you
|
|
||||||
use Nginx_. If you choose another proxy server you need to make sure that it
|
|
||||||
buffers slow clients when you use default Gunicorn workers. Without this
|
|
||||||
buffering Gunicorn will be easily susceptible to denial-of-service attacks.
|
|
||||||
You can use Hey_ to check if your proxy is behaving properly.
|
|
||||||
|
|
||||||
An `example configuration`_ file for fast clients with Nginx_:
|
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/nginx.conf
|
|
||||||
:language: nginx
|
|
||||||
:caption: **nginx.conf**
|
|
||||||
|
|
||||||
If you want to be able to handle streaming request/responses or other fancy
|
|
||||||
features like Comet, Long polling, or Web sockets, you need to turn off the
|
|
||||||
proxy buffering. **When you do this** you must run with one of the async worker
|
|
||||||
classes.
|
|
||||||
|
|
||||||
To turn off buffering, you only need to add ``proxy_buffering off;`` to your
|
|
||||||
``location`` block::
|
|
||||||
|
|
||||||
...
|
|
||||||
location @proxy_to_app {
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_redirect off;
|
|
||||||
proxy_buffering off;
|
|
||||||
|
|
||||||
proxy_pass http://app_server;
|
|
||||||
}
|
|
||||||
...
|
|
||||||
|
|
||||||
If you want to ignore aborted requests like health check of Load Balancer, some
|
|
||||||
of which close the connection without waiting for a response, you need to turn
|
|
||||||
on `ignoring client abort`_.
|
|
||||||
|
|
||||||
To ignore aborted requests, you only need to add
|
|
||||||
``proxy_ignore_client_abort on;`` to your ``location`` block::
|
|
||||||
|
|
||||||
...
|
|
||||||
proxy_ignore_client_abort on;
|
|
||||||
...
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
The default value of ``proxy_ignore_client_abort`` is ``off``. Error code
|
|
||||||
499 may appear in Nginx log and ``Ignoring EPIPE`` may appear in Gunicorn
|
|
||||||
log if loglevel is set to ``debug``.
|
|
||||||
|
|
||||||
It is recommended to pass protocol information to Gunicorn. Many web
|
|
||||||
frameworks use this information to generate URLs. Without this
|
|
||||||
information, the application may mistakenly generate 'http' URLs in
|
|
||||||
'https' responses, leading to mixed content warnings or broken
|
|
||||||
applications. To configure Nginx to pass an appropriate header, add
|
|
||||||
a ``proxy_set_header`` directive to your ``location`` block::
|
|
||||||
|
|
||||||
...
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
...
|
|
||||||
|
|
||||||
If you are running Nginx on a different host than Gunicorn you need to tell
|
|
||||||
Gunicorn to trust the ``X-Forwarded-*`` headers sent by Nginx. By default,
|
|
||||||
Gunicorn will only trust these headers if the connection comes from localhost.
|
|
||||||
This is to prevent a malicious client from forging these headers::
|
|
||||||
|
|
||||||
$ gunicorn -w 3 --forwarded-allow-ips="10.170.3.217,10.170.3.220" test:app
|
|
||||||
|
|
||||||
When the Gunicorn host is completely firewalled from the external network such
|
|
||||||
that all connections come from a trusted proxy (e.g. Heroku) this value can
|
|
||||||
be set to '*'. Using this value is **potentially dangerous** if connections to
|
|
||||||
Gunicorn may come from untrusted proxies or directly from clients since the
|
|
||||||
application may be tricked into serving SSL-only content over an insecure
|
|
||||||
connection.
|
|
||||||
|
|
||||||
Gunicorn 19 introduced a breaking change concerning how ``REMOTE_ADDR`` is
|
|
||||||
handled. Previous to Gunicorn 19 this was set to the value of
|
|
||||||
``X-Forwarded-For`` if received from a trusted proxy. However, this was not in
|
|
||||||
compliance with :rfc:`3875` which is why the ``REMOTE_ADDR`` is now the IP
|
|
||||||
address of **the proxy** and **not the actual user**.
|
|
||||||
|
|
||||||
To have access logs indicate **the actual user** IP when proxied, set
|
|
||||||
:ref:`access-log-format` with a format which includes ``X-Forwarded-For``. For
|
|
||||||
example, this format uses ``X-Forwarded-For`` in place of ``REMOTE_ADDR``::
|
|
||||||
|
|
||||||
%({x-forwarded-for}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
|
|
||||||
|
|
||||||
It is also worth noting that the ``REMOTE_ADDR`` will be completely empty if
|
|
||||||
you bind Gunicorn to a UNIX socket and not a TCP ``host:port`` tuple.
|
|
||||||
|
|
||||||
Using Virtualenv
|
|
||||||
================
|
|
||||||
|
|
||||||
To serve an app from a Virtualenv_ it is generally easiest to just install
|
|
||||||
Gunicorn directly into the Virtualenv. This will create a set of Gunicorn
|
|
||||||
scripts for that Virtualenv which can be used to run applications normally.
|
|
||||||
|
|
||||||
If you have Virtualenv installed, you should be able to do something like
|
|
||||||
this::
|
|
||||||
|
|
||||||
$ mkdir ~/venvs/
|
|
||||||
$ virtualenv ~/venvs/webapp
|
|
||||||
$ source ~/venvs/webapp/bin/activate
|
|
||||||
$ pip install gunicorn
|
|
||||||
$ deactivate
|
|
||||||
|
|
||||||
Then you just need to use one of the three Gunicorn scripts that was installed
|
|
||||||
into ``~/venvs/webapp/bin``.
|
|
||||||
|
|
||||||
Note: You can force the installation of Gunicorn in your Virtualenv by
|
|
||||||
passing ``-I`` or ``--ignore-installed`` option to pip::
|
|
||||||
|
|
||||||
$ source ~/venvs/webapp/bin/activate
|
|
||||||
$ pip install -I gunicorn
|
|
||||||
|
|
||||||
Monitoring
|
|
||||||
==========
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
Make sure that when using either of these service monitors you do not
|
|
||||||
enable the Gunicorn's daemon mode. These monitors expect that the process
|
|
||||||
they launch will be the process they need to monitor. Daemonizing will
|
|
||||||
fork-exec which creates an unmonitored process and generally just
|
|
||||||
confuses the monitor services.
|
|
||||||
|
|
||||||
Gaffer
|
|
||||||
------
|
|
||||||
|
|
||||||
Using Gafferd and gaffer
|
|
||||||
++++++++++++++++++++++++
|
|
||||||
|
|
||||||
Gaffer_ can be used to monitor Gunicorn. A simple configuration is::
|
|
||||||
|
|
||||||
[process:gunicorn]
|
|
||||||
cmd = gunicorn -w 3 test:app
|
|
||||||
cwd = /path/to/project
|
|
||||||
|
|
||||||
Then you can easily manage Gunicorn using Gaffer_.
|
|
||||||
|
|
||||||
|
|
||||||
Using a Procfile
|
|
||||||
++++++++++++++++
|
|
||||||
|
|
||||||
Create a ``Procfile`` in your project::
|
|
||||||
|
|
||||||
gunicorn = gunicorn -w 3 test:app
|
|
||||||
|
|
||||||
You can launch any other applications that should be launched at the same time.
|
|
||||||
|
|
||||||
Then you can start your Gunicorn application using Gaffer_::
|
|
||||||
|
|
||||||
gaffer start
|
|
||||||
|
|
||||||
If gafferd is launched you can also load your Procfile in it directly::
|
|
||||||
|
|
||||||
gaffer load
|
|
||||||
|
|
||||||
All your applications will be then supervised by gafferd.
|
|
||||||
|
|
||||||
Runit
|
|
||||||
-----
|
|
||||||
|
|
||||||
A popular method for deploying Gunicorn is to have it monitored by runit_.
|
|
||||||
Here is an `example service`_ definition::
|
|
||||||
|
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
GUNICORN=/usr/local/bin/gunicorn
|
|
||||||
ROOT=/path/to/project
|
|
||||||
PID=/var/run/gunicorn.pid
|
|
||||||
|
|
||||||
APP=main:application
|
|
||||||
|
|
||||||
if [ -f $PID ]; then rm $PID; fi
|
|
||||||
|
|
||||||
cd $ROOT
|
|
||||||
exec $GUNICORN -c $ROOT/gunicorn.conf.py --pid=$PID $APP
|
|
||||||
|
|
||||||
Save this as ``/etc/sv/[app_name]/run``, and make it executable
|
|
||||||
(``chmod u+x /etc/sv/[app_name]/run``).
|
|
||||||
Then run ``ln -s /etc/sv/[app_name] /etc/service/[app_name]``.
|
|
||||||
If runit is installed, Gunicorn should start running automatically as soon
|
|
||||||
as you create the symlink.
|
|
||||||
|
|
||||||
If it doesn't start automatically, run the script directly to troubleshoot.
|
|
||||||
|
|
||||||
Supervisor
|
|
||||||
----------
|
|
||||||
|
|
||||||
Another useful tool to monitor and control Gunicorn is Supervisor_. A
|
|
||||||
`simple configuration`_ is::
|
|
||||||
|
|
||||||
[program:gunicorn]
|
|
||||||
command=/path/to/gunicorn main:application -c /path/to/gunicorn.conf.py
|
|
||||||
directory=/path/to/project
|
|
||||||
user=nobody
|
|
||||||
autostart=true
|
|
||||||
autorestart=true
|
|
||||||
redirect_stderr=true
|
|
||||||
|
|
||||||
Upstart
|
|
||||||
-------
|
|
||||||
|
|
||||||
Using Gunicorn with upstart is simple. In this example we will run the app
|
|
||||||
"myapp" from a virtualenv. All errors will go to
|
|
||||||
``/var/log/upstart/myapp.log``.
|
|
||||||
|
|
||||||
**/etc/init/myapp.conf**::
|
|
||||||
|
|
||||||
description "myapp"
|
|
||||||
|
|
||||||
start on (filesystem)
|
|
||||||
stop on runlevel [016]
|
|
||||||
|
|
||||||
respawn
|
|
||||||
setuid nobody
|
|
||||||
setgid nogroup
|
|
||||||
chdir /path/to/app/directory
|
|
||||||
|
|
||||||
exec /path/to/virtualenv/bin/gunicorn myapp:app
|
|
||||||
|
|
||||||
Systemd
|
|
||||||
-------
|
|
||||||
|
|
||||||
A tool that is starting to be common on linux systems is Systemd_. It is a
|
|
||||||
system services manager that allows for strict process management, resources
|
|
||||||
and permissions control.
|
|
||||||
|
|
||||||
Below are configuration files and instructions for using systemd to create
|
|
||||||
a unix socket for incoming Gunicorn requests. Systemd will listen on this
|
|
||||||
socket and start gunicorn automatically in response to traffic. Later in
|
|
||||||
this section are instructions for configuring Nginx to forward web traffic
|
|
||||||
to the newly created unix socket:
|
|
||||||
|
|
||||||
**/etc/systemd/system/gunicorn.service**::
|
|
||||||
|
|
||||||
[Unit]
|
|
||||||
Description=gunicorn daemon
|
|
||||||
Requires=gunicorn.socket
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
# gunicorn can let systemd know when it is ready
|
|
||||||
Type=notify
|
|
||||||
NotifyAccess=main
|
|
||||||
# the specific user that our service will run as
|
|
||||||
User=someuser
|
|
||||||
Group=someuser
|
|
||||||
# this user can be transiently created by systemd
|
|
||||||
# DynamicUser=true
|
|
||||||
RuntimeDirectory=gunicorn
|
|
||||||
WorkingDirectory=/home/someuser/applicationroot
|
|
||||||
ExecStart=/usr/bin/gunicorn applicationname.wsgi
|
|
||||||
ExecReload=/bin/kill -s HUP $MAINPID
|
|
||||||
KillMode=mixed
|
|
||||||
TimeoutStopSec=5
|
|
||||||
PrivateTmp=true
|
|
||||||
# if your app does not need administrative capabilities, let systemd know
|
|
||||||
# ProtectSystem=strict
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
|
|
||||||
**/etc/systemd/system/gunicorn.socket**::
|
|
||||||
|
|
||||||
[Unit]
|
|
||||||
Description=gunicorn socket
|
|
||||||
|
|
||||||
[Socket]
|
|
||||||
ListenStream=/run/gunicorn.sock
|
|
||||||
# Our service won't need permissions for the socket, since it
|
|
||||||
# inherits the file descriptor by socket activation.
|
|
||||||
# Only the nginx daemon will need access to the socket:
|
|
||||||
SocketUser=www-data
|
|
||||||
SocketGroup=www-data
|
|
||||||
# Once the user/group is correct, restrict the permissions:
|
|
||||||
SocketMode=0660
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=sockets.target
|
|
||||||
|
|
||||||
|
|
||||||
Next enable and start the socket (it will autostart at boot too)::
|
|
||||||
|
|
||||||
systemctl enable --now gunicorn.socket
|
|
||||||
|
|
||||||
|
|
||||||
Now let's see if the nginx daemon will be able to connect to the socket.
|
|
||||||
Running ``sudo -u www-data curl --unix-socket /run/gunicorn.sock http``,
|
|
||||||
our Gunicorn service will be automatically started and you should see some
|
|
||||||
HTML from your server in the terminal.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
systemd employs cgroups to track the processes of a service, so it doesn't
|
|
||||||
need pid files. In the rare case that you need to find out the service main
|
|
||||||
pid, you can use ``systemctl show --value -p MainPID gunicorn.service``, but
|
|
||||||
if you only want to send a signal an even better option is
|
|
||||||
``systemctl kill -s HUP gunicorn.service``.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
``www-data`` is the default nginx user in debian, other distributions use
|
|
||||||
different users (for example: ``http`` or ``nginx``). Check your distro to
|
|
||||||
know what to put for the socket user, and for the sudo command.
|
|
||||||
|
|
||||||
You must now configure your web proxy to send traffic to the new Gunicorn
|
|
||||||
socket. Edit your ``nginx.conf`` to include the following:
|
|
||||||
|
|
||||||
**/etc/nginx/nginx.conf**::
|
|
||||||
|
|
||||||
user www-data;
|
|
||||||
...
|
|
||||||
http {
|
|
||||||
server {
|
|
||||||
listen 8000;
|
|
||||||
server_name 127.0.0.1;
|
|
||||||
location / {
|
|
||||||
proxy_pass http://unix:/run/gunicorn.sock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
...
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The listen and server_name used here are configured for a local machine.
|
|
||||||
In a production server you will most likely listen on port 80,
|
|
||||||
and use your URL as the server_name.
|
|
||||||
|
|
||||||
Now make sure you enable the nginx service so it automatically starts at boot::
|
|
||||||
|
|
||||||
systemctl enable nginx.service
|
|
||||||
|
|
||||||
Either reboot, or start Nginx with the following command::
|
|
||||||
|
|
||||||
systemctl start nginx
|
|
||||||
|
|
||||||
Now you should be able to test Nginx with Gunicorn by visiting
|
|
||||||
http://127.0.0.1:8000/ in any web browser. Systemd is now set up.
|
|
||||||
|
|
||||||
|
|
||||||
Logging
|
|
||||||
=======
|
|
||||||
|
|
||||||
Logging can be configured by using various flags detailed in the
|
|
||||||
`configuration documentation`_ or by creating a `logging configuration file`_.
|
|
||||||
Send the ``USR1`` signal to rotate logs if you are using the logrotate
|
|
||||||
utility::
|
|
||||||
|
|
||||||
kill -USR1 $(cat /var/run/gunicorn.pid)
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
Overriding the ``LOGGING`` dictionary requires to set
|
|
||||||
``disable_existing_loggers: False`` to not interfere with the Gunicorn
|
|
||||||
logging.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
Gunicorn error log is here to log errors from Gunicorn, not from another
|
|
||||||
application.
|
|
||||||
|
|
||||||
.. _Nginx: https://nginx.org/
|
|
||||||
.. _Hey: https://github.com/rakyll/hey
|
|
||||||
.. _`example configuration`: https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf
|
|
||||||
.. _runit: http://smarden.org/runit/
|
|
||||||
.. _`example service`: https://github.com/benoitc/gunicorn/blob/master/examples/gunicorn_rc
|
|
||||||
.. _Supervisor: http://supervisord.org/
|
|
||||||
.. _`simple configuration`: https://github.com/benoitc/gunicorn/blob/master/examples/supervisor.conf
|
|
||||||
.. _`configuration documentation`: http://docs.gunicorn.org/en/latest/settings.html#logging
|
|
||||||
.. _`logging configuration file`: https://github.com/benoitc/gunicorn/blob/master/examples/logging.conf
|
|
||||||
.. _Virtualenv: https://pypi.python.org/pypi/virtualenv
|
|
||||||
.. _Systemd: https://www.freedesktop.org/wiki/Software/systemd/
|
|
||||||
.. _Gaffer: https://gaffer.readthedocs.io/
|
|
||||||
.. _`ignoring client abort`: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_client_abort
|
|
||||||
@ -1,150 +0,0 @@
|
|||||||
|
|
||||||
.. _design:
|
|
||||||
|
|
||||||
======
|
|
||||||
Design
|
|
||||||
======
|
|
||||||
|
|
||||||
A brief description of the architecture of Gunicorn.
|
|
||||||
|
|
||||||
Server Model
|
|
||||||
============
|
|
||||||
|
|
||||||
Gunicorn is based on the pre-fork worker model. This means that there is a
|
|
||||||
central master process that manages a set of worker processes. The master
|
|
||||||
never knows anything about individual clients. All requests and responses are
|
|
||||||
handled completely by worker processes.
|
|
||||||
|
|
||||||
Master
|
|
||||||
------
|
|
||||||
|
|
||||||
The master process is a simple loop that listens for various process signals
|
|
||||||
and reacts accordingly. It manages the list of running workers by listening
|
|
||||||
for signals like TTIN, TTOU, and CHLD. TTIN and TTOU tell the master to
|
|
||||||
increase or decrease the number of running workers. CHLD indicates that a child
|
|
||||||
process has terminated, in this case the master process automatically restarts
|
|
||||||
the failed worker.
|
|
||||||
|
|
||||||
Sync Workers
|
|
||||||
------------
|
|
||||||
|
|
||||||
The most basic and the default worker type is a synchronous worker class that
|
|
||||||
handles a single request at a time. This model is the simplest to reason about
|
|
||||||
as any errors will affect at most a single request. Though as we describe below
|
|
||||||
only processing a single request at a time requires some assumptions about how
|
|
||||||
applications are programmed.
|
|
||||||
|
|
||||||
``sync`` worker does not support persistent connections - each connection is
|
|
||||||
closed after response has been sent (even if you manually add ``Keep-Alive``
|
|
||||||
or ``Connection: keep-alive`` header in your application).
|
|
||||||
|
|
||||||
Async Workers
|
|
||||||
-------------
|
|
||||||
|
|
||||||
The asynchronous workers available are based on Greenlets_ (via Eventlet_ and
|
|
||||||
Gevent_). Greenlets are an implementation of cooperative multi-threading for
|
|
||||||
Python. In general, an application should be able to make use of these worker
|
|
||||||
classes with no changes.
|
|
||||||
|
|
||||||
For full greenlet support applications might need to be adapted.
|
|
||||||
When using, e.g., Gevent_ and Psycopg_ it makes sense to ensure psycogreen_ is
|
|
||||||
installed and `setup <http://www.gevent.org/api/gevent.monkey.html#plugins>`_.
|
|
||||||
|
|
||||||
Other applications might not be compatible at all as they, e.g., rely on
|
|
||||||
the original unpatched behavior.
|
|
||||||
|
|
||||||
Gthread Workers
|
|
||||||
---------------
|
|
||||||
|
|
||||||
The worker `gthread` is a threaded worker. It accepts connections in the
|
|
||||||
main loop. Accepted connections are added to the thread pool as a
|
|
||||||
connection job. On keepalive connections are put back in the loop
|
|
||||||
waiting for an event. If no event happens after the keepalive timeout,
|
|
||||||
the connection is closed.
|
|
||||||
|
|
||||||
Tornado Workers
|
|
||||||
---------------
|
|
||||||
|
|
||||||
There's also a Tornado worker class. It can be used to write applications using
|
|
||||||
the Tornado framework. Although the Tornado workers are capable of serving a
|
|
||||||
WSGI application, this is not a recommended configuration.
|
|
||||||
|
|
||||||
|
|
||||||
.. _asyncio-workers:
|
|
||||||
|
|
||||||
AsyncIO Workers
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Third-party workers can be used to use Gunicorn with asyncio frameworks.
|
|
||||||
|
|
||||||
Choosing a Worker Type
|
|
||||||
======================
|
|
||||||
|
|
||||||
The default synchronous workers assume that your application is resource-bound
|
|
||||||
in terms of CPU and network bandwidth. Generally this means that your
|
|
||||||
application shouldn't do anything that takes an undefined amount of time. An
|
|
||||||
example of something that takes an undefined amount of time is a request to the
|
|
||||||
internet. At some point the external network will fail in such a way that
|
|
||||||
clients will pile up on your servers. So, in this sense, any web application
|
|
||||||
which makes outgoing requests to APIs will benefit from an asynchronous worker.
|
|
||||||
|
|
||||||
This resource bound assumption is why we require a buffering proxy in front of
|
|
||||||
a default configuration Gunicorn. If you exposed synchronous workers to the
|
|
||||||
internet, a DOS attack would be trivial by creating a load that trickles data to
|
|
||||||
the servers. For the curious, Hey_ is an example of this type of load.
|
|
||||||
|
|
||||||
|
|
||||||
Some examples of behavior requiring asynchronous workers:
|
|
||||||
|
|
||||||
* Applications making long blocking calls (Ie, external web services)
|
|
||||||
* Serving requests directly to the internet
|
|
||||||
* Streaming requests and responses
|
|
||||||
* Long polling
|
|
||||||
* Web sockets
|
|
||||||
* Comet
|
|
||||||
|
|
||||||
How Many Workers?
|
|
||||||
=================
|
|
||||||
|
|
||||||
DO NOT scale the number of workers to the number of clients you expect to have.
|
|
||||||
Gunicorn should only need 4-12 worker processes to handle hundreds or thousands
|
|
||||||
of requests per second.
|
|
||||||
|
|
||||||
Gunicorn relies on the operating system to provide all of the load balancing
|
|
||||||
when handling requests. Generally we recommend ``(2 x $num_cores) + 1`` as the
|
|
||||||
number of workers to start off with. While not overly scientific, the formula
|
|
||||||
is based on the assumption that for a given core, one worker will be reading
|
|
||||||
or writing from the socket while the other worker is processing a request.
|
|
||||||
|
|
||||||
Obviously, your particular hardware and application are going to affect the
|
|
||||||
optimal number of workers. Our recommendation is to start with the above guess
|
|
||||||
and tune using TTIN and TTOU signals while the application is under load.
|
|
||||||
|
|
||||||
Always remember, there is such a thing as too many workers. After a point your
|
|
||||||
worker processes will start thrashing system resources decreasing the
|
|
||||||
throughput of the entire system.
|
|
||||||
|
|
||||||
How Many Threads?
|
|
||||||
===================
|
|
||||||
|
|
||||||
Since Gunicorn 19, a threads option can be used to process requests in multiple
|
|
||||||
threads. Using threads assumes use of the gthread worker. One benefit from threads
|
|
||||||
is that requests can take longer than the worker timeout while notifying the
|
|
||||||
master process that it is not frozen and should not be killed. Depending on the
|
|
||||||
system, using multiple threads, multiple worker processes, or some mixture, may
|
|
||||||
yield the best results. For example, CPython may not perform as well as Jython
|
|
||||||
when using threads, as threading is implemented differently by each. Using
|
|
||||||
threads instead of processes is a good way to reduce the memory footprint of
|
|
||||||
Gunicorn, while still allowing for application upgrades using the reload
|
|
||||||
signal, as the application code will be shared among workers but loaded only in
|
|
||||||
the worker processes (unlike when using the preload setting, which loads the
|
|
||||||
code in the master process).
|
|
||||||
|
|
||||||
.. _Greenlets: https://github.com/python-greenlet/greenlet
|
|
||||||
.. _Eventlet: http://eventlet.net/
|
|
||||||
.. _Gevent: http://www.gevent.org/
|
|
||||||
.. _Hey: https://github.com/rakyll/hey
|
|
||||||
.. _aiohttp: https://docs.aiohttp.org/en/stable/deployment.html#nginx-gunicorn
|
|
||||||
.. _`example`: https://github.com/benoitc/gunicorn/blob/master/examples/frameworks/flaskapp_aiohttp_wsgi.py
|
|
||||||
.. _Psycopg: http://initd.org/psycopg/
|
|
||||||
.. _psycogreen: https://github.com/psycopg/psycogreen/
|
|
||||||
@ -1,244 +0,0 @@
|
|||||||
.. _faq:
|
|
||||||
|
|
||||||
===
|
|
||||||
FAQ
|
|
||||||
===
|
|
||||||
|
|
||||||
WSGI Bits
|
|
||||||
=========
|
|
||||||
|
|
||||||
How do I set SCRIPT_NAME?
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
By default ``SCRIPT_NAME`` is an empty string. The value could be set by
|
|
||||||
setting ``SCRIPT_NAME`` in the environment or as an HTTP header. Note that
|
|
||||||
this headers contains and underscore, so it is only accepted from trusted
|
|
||||||
forwarders listed in the :ref:`forwarded-allow-ips` setting.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
If your application should appear in a subfolder, your ``SCRIPT_NAME``
|
|
||||||
would typically start with single slash but contain no trailing slash.
|
|
||||||
|
|
||||||
Server Stuff
|
|
||||||
============
|
|
||||||
|
|
||||||
How do I reload my application in Gunicorn?
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
You can gracefully reload by sending HUP signal to gunicorn::
|
|
||||||
|
|
||||||
$ kill -HUP masterpid
|
|
||||||
|
|
||||||
How might I test a proxy configuration?
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
The Hey_ program is a great way to test that your proxy is correctly
|
|
||||||
buffering responses for the synchronous workers::
|
|
||||||
|
|
||||||
$ hey -n 10000 -c 100 http://127.0.0.1:5000/
|
|
||||||
|
|
||||||
This runs a benchmark of 10000 requests with 100 running concurrently.
|
|
||||||
|
|
||||||
How can I name processes?
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
If you install the Python package setproctitle_ Gunicorn will set the process
|
|
||||||
names to something a bit more meaningful. This will affect the output you see
|
|
||||||
in tools like ``ps`` and ``top``. This helps for distinguishing the master
|
|
||||||
process as well as between masters when running more than one app on a single
|
|
||||||
machine. See the proc_name_ setting for more information.
|
|
||||||
|
|
||||||
Why is there no HTTP Keep-Alive?
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
The default Sync workers are designed to run behind Nginx which only uses
|
|
||||||
HTTP/1.0 with its upstream servers. If you want to deploy Gunicorn to
|
|
||||||
handle unbuffered requests (ie, serving requests directly from the internet)
|
|
||||||
you should use one of the async workers.
|
|
||||||
|
|
||||||
.. _Hey: https://github.com/rakyll/hey
|
|
||||||
.. _setproctitle: https://pypi.python.org/pypi/setproctitle
|
|
||||||
.. _proc_name: settings.html#proc-name
|
|
||||||
|
|
||||||
|
|
||||||
Worker Processes
|
|
||||||
================
|
|
||||||
|
|
||||||
How do I know which type of worker to use?
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
Read the :ref:`design` page for help on the various worker types.
|
|
||||||
|
|
||||||
What types of workers are there?
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
Check out the configuration docs for worker_class_.
|
|
||||||
|
|
||||||
How can I figure out the best number of worker processes?
|
|
||||||
---------------------------------------------------------
|
|
||||||
|
|
||||||
Here is our recommendation for tuning the `number of workers`_.
|
|
||||||
|
|
||||||
How can I change the number of workers dynamically?
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
TTIN and TTOU signals can be sent to the master to increase or decrease
|
|
||||||
the number of workers.
|
|
||||||
|
|
||||||
To increase the worker count by one::
|
|
||||||
|
|
||||||
$ kill -TTIN $masterpid
|
|
||||||
|
|
||||||
To decrease the worker count by one::
|
|
||||||
|
|
||||||
$ kill -TTOU $masterpid
|
|
||||||
|
|
||||||
Does Gunicorn suffer from the thundering herd problem?
|
|
||||||
------------------------------------------------------
|
|
||||||
|
|
||||||
The thundering herd problem occurs when many sleeping request handlers, which
|
|
||||||
may be either threads or processes, wake up at the same time to handle a new
|
|
||||||
request. Since only one handler will receive the request, the others will have
|
|
||||||
been awakened for no reason, wasting CPU cycles. At this time, Gunicorn does
|
|
||||||
not implement any IPC solution for coordinating between worker processes. You
|
|
||||||
may experience high load due to this problem when using many workers or
|
|
||||||
threads. However `a work has been started
|
|
||||||
<https://github.com/benoitc/gunicorn/issues/792>`_ to remove this issue.
|
|
||||||
|
|
||||||
.. _worker_class: settings.html#worker-class
|
|
||||||
.. _`number of workers`: design.html#how-many-workers
|
|
||||||
|
|
||||||
Why I don't see any logs in the console?
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
In version 19.0, Gunicorn doesn't log by default in the console.
|
|
||||||
To watch the logs in the console you need to use the option ``--log-file=-``.
|
|
||||||
In version 19.2, Gunicorn logs to the console by default again.
|
|
||||||
|
|
||||||
Kernel Parameters
|
|
||||||
=================
|
|
||||||
|
|
||||||
When dealing with large numbers of concurrent connections there are a handful
|
|
||||||
of kernel parameters that you might need to adjust. Generally these should only
|
|
||||||
affect sites with a very large concurrent load. These parameters are not
|
|
||||||
specific to Gunicorn, they would apply to any sort of network server you may be
|
|
||||||
running.
|
|
||||||
|
|
||||||
These commands are for Linux. Your particular OS may have slightly different
|
|
||||||
parameters.
|
|
||||||
|
|
||||||
How can I increase the maximum number of file descriptors?
|
|
||||||
----------------------------------------------------------
|
|
||||||
|
|
||||||
One of the first settings that usually needs to be bumped is the maximum number
|
|
||||||
of open file descriptors for a given process. For the confused out there,
|
|
||||||
remember that Unices treat sockets as files.
|
|
||||||
|
|
||||||
.. warning:: ``sudo ulimit`` may not work
|
|
||||||
|
|
||||||
Considering non-privileged users are not able to relax the limit, you should
|
|
||||||
firstly switch to root user, increase the limit, then run gunicorn. Using ``sudo
|
|
||||||
ulimit`` would not take effect.
|
|
||||||
|
|
||||||
Try systemd's service unit file, or an initscript which runs as root.
|
|
||||||
|
|
||||||
How can I increase the maximum socket backlog?
|
|
||||||
----------------------------------------------
|
|
||||||
|
|
||||||
Listening sockets have an associated queue of incoming connections that are
|
|
||||||
waiting to be accepted. If you happen to have a stampede of clients that fill
|
|
||||||
up this queue new connections will eventually start getting dropped.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$ sudo sysctl -w net.core.somaxconn="2048"
|
|
||||||
|
|
||||||
How can I disable the use of ``sendfile()``
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
Disabling the use ``sendfile()`` can be done by using the ``--no-sendfile``
|
|
||||||
setting or by setting the environment variable ``SENDFILE`` to 0.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Troubleshooting
|
|
||||||
===============
|
|
||||||
|
|
||||||
How do I fix Django reporting an ``ImproperlyConfigured`` error?
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
With asynchronous workers, creating URLs with the ``reverse`` function of
|
|
||||||
``django.core.urlresolvers`` may fail. Use ``reverse_lazy`` instead.
|
|
||||||
|
|
||||||
.. _blocking-os-fchmod:
|
|
||||||
|
|
||||||
How do I avoid Gunicorn excessively blocking in ``os.fchmod``?
|
|
||||||
--------------------------------------------------------------
|
|
||||||
|
|
||||||
The current heartbeat system involves calling ``os.fchmod`` on temporary file
|
|
||||||
handlers and may block a worker for arbitrary time if the directory is on a
|
|
||||||
disk-backed filesystem. For example, by default ``/tmp`` is not mounted as
|
|
||||||
``tmpfs`` in Ubuntu; in AWS an EBS root instance volume may sometimes hang for
|
|
||||||
half a minute and during this time Gunicorn workers may completely block in
|
|
||||||
``os.fchmod``. ``os.fchmod`` may introduce extra delays if the disk gets full.
|
|
||||||
Also Gunicorn may refuse to start if it can't create the files when the disk is
|
|
||||||
full.
|
|
||||||
|
|
||||||
Currently to avoid these problems you can use a ``tmpfs`` mount (for a new
|
|
||||||
directory or for ``/tmp``) and pass its path to ``--worker-tmp-dir``. First,
|
|
||||||
check whether your ``/tmp`` is disk-backed or RAM-backed::
|
|
||||||
|
|
||||||
$ df /tmp
|
|
||||||
Filesystem 1K-blocks Used Available Use% Mounted on
|
|
||||||
/dev/xvda1 ... ... ... ... /
|
|
||||||
|
|
||||||
No luck. If you are using Fedora or Ubuntu, you should already have a ``tmpfs``
|
|
||||||
mount at ``/dev/shm``::
|
|
||||||
|
|
||||||
$ df /dev/shm
|
|
||||||
Filesystem 1K-blocks Used Available Use% Mounted on
|
|
||||||
tmpfs ... ... ... ... /dev/shm
|
|
||||||
|
|
||||||
In this case you can set ``--worker-tmp-dir /dev/shm``, otherwise you can
|
|
||||||
create a new ``tmpfs`` mount::
|
|
||||||
|
|
||||||
sudo cp /etc/fstab /etc/fstab.orig
|
|
||||||
sudo mkdir /mem
|
|
||||||
echo 'tmpfs /mem tmpfs defaults,size=64m,mode=1777,noatime,comment=for-gunicorn 0 0' | sudo tee -a /etc/fstab
|
|
||||||
sudo mount /mem
|
|
||||||
|
|
||||||
Check the result::
|
|
||||||
|
|
||||||
$ df /mem
|
|
||||||
Filesystem 1K-blocks Used Available Use% Mounted on
|
|
||||||
tmpfs 65536 0 65536 0% /mem
|
|
||||||
|
|
||||||
Now you can set ``--worker-tmp-dir /mem``.
|
|
||||||
|
|
||||||
Why are Workers Silently Killed?
|
|
||||||
--------------------------------------------------------------
|
|
||||||
|
|
||||||
A sometimes subtle problem to debug is when a worker process is killed and there
|
|
||||||
is little logging information about what happened.
|
|
||||||
|
|
||||||
If you use a reverse proxy like NGINX you might see 502 returned to a client.
|
|
||||||
|
|
||||||
In the gunicorn logs you might simply see ``[35] [INFO] Booting worker with pid: 35``
|
|
||||||
|
|
||||||
It's completely normal for workers to be stop and start, for example due to
|
|
||||||
max-requests setting. Ordinarily gunicorn will capture any signals and log something.
|
|
||||||
|
|
||||||
This particular failure case is usually due to a SIGKILL being received, as it's
|
|
||||||
not possible to catch this signal silence is usually a common side effect! A common
|
|
||||||
cause of SIGKILL is when OOM killer terminates a process due to low memory condition.
|
|
||||||
|
|
||||||
This is increasingly common in container deployments where memory limits are enforced
|
|
||||||
by cgroups, you'll usually see evidence of this from dmesg::
|
|
||||||
|
|
||||||
dmesg | grep gunicorn
|
|
||||||
Memory cgroup out of memory: Kill process 24534 (gunicorn) score 1506 or sacrifice child
|
|
||||||
Killed process 24534 (gunicorn) total-vm:1016648kB, anon-rss:550160kB, file-rss:25824kB, shmem-rss:0kB
|
|
||||||
|
|
||||||
In these instances adjusting the memory limit is usually your best bet, it's also possible
|
|
||||||
to configure OOM not to send SIGKILL by default.
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
======================
|
|
||||||
Gunicorn - WSGI server
|
|
||||||
======================
|
|
||||||
|
|
||||||
.. image:: _static/gunicorn.png
|
|
||||||
|
|
||||||
:Website: http://gunicorn.org
|
|
||||||
:Source code: https://github.com/benoitc/gunicorn
|
|
||||||
:Issue tracker: https://github.com/benoitc/gunicorn/issues
|
|
||||||
:IRC: ``#gunicorn`` on Libera Chat
|
|
||||||
:Usage questions: https://github.com/benoitc/gunicorn/issues
|
|
||||||
|
|
||||||
Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork
|
|
||||||
worker model ported from Ruby's Unicorn project. The Gunicorn server is broadly
|
|
||||||
compatible with various web frameworks, simply implemented, light on server
|
|
||||||
resources, and fairly speedy.
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
* Natively supports WSGI, Django, and Paster
|
|
||||||
* Automatic worker process management
|
|
||||||
* Simple Python configuration
|
|
||||||
* Multiple worker configurations
|
|
||||||
* Various server hooks for extensibility
|
|
||||||
* Compatible with Python 3.x >= 3.10
|
|
||||||
|
|
||||||
|
|
||||||
Contents
|
|
||||||
--------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
install
|
|
||||||
run
|
|
||||||
configure
|
|
||||||
settings
|
|
||||||
instrumentation
|
|
||||||
deploy
|
|
||||||
signals
|
|
||||||
custom
|
|
||||||
design
|
|
||||||
faq
|
|
||||||
community
|
|
||||||
news
|
|
||||||
@ -1,172 +0,0 @@
|
|||||||
============
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
.. highlight:: bash
|
|
||||||
|
|
||||||
:Requirements: **Python 3.x >= 3.10**
|
|
||||||
|
|
||||||
To install the latest released version of Gunicorn::
|
|
||||||
|
|
||||||
$ pip install gunicorn
|
|
||||||
|
|
||||||
From Source
|
|
||||||
===========
|
|
||||||
|
|
||||||
You can install Gunicorn from source just as you would install any other
|
|
||||||
Python package::
|
|
||||||
|
|
||||||
$ pip install git+https://github.com/benoitc/gunicorn.git
|
|
||||||
|
|
||||||
This will allow you to keep up to date with development on GitHub::
|
|
||||||
|
|
||||||
$ pip install -U git+https://github.com/benoitc/gunicorn.git
|
|
||||||
|
|
||||||
|
|
||||||
Async Workers
|
|
||||||
=============
|
|
||||||
|
|
||||||
You may also want to install Eventlet_ or Gevent_ if you expect that your
|
|
||||||
application code may need to pause for extended periods of time during request
|
|
||||||
processing. Check out the `design docs`_ for more information on when you'll
|
|
||||||
want to consider one of the alternate worker types.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$ pip install greenlet # Required for both
|
|
||||||
$ pip install eventlet # For eventlet workers
|
|
||||||
$ pip install gunicorn[eventlet] # Or, using extra
|
|
||||||
$ pip install gevent # For gevent workers
|
|
||||||
$ pip install gunicorn[gevent] # Or, using extra
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
Both require ``greenlet``, which should get installed automatically.
|
|
||||||
If its installation fails, you probably need to install
|
|
||||||
the Python headers. These headers are available in most package
|
|
||||||
managers. On Ubuntu the package name for ``apt-get`` is
|
|
||||||
``python-dev``.
|
|
||||||
|
|
||||||
Gevent_ also requires that ``libevent`` 1.4.x or 2.0.4 is installed.
|
|
||||||
This could be a more recent version than what is available in your
|
|
||||||
package manager. If Gevent_ fails to build even with libevent_
|
|
||||||
installed, this is the most likely reason.
|
|
||||||
|
|
||||||
|
|
||||||
Extra Packages
|
|
||||||
==============
|
|
||||||
Some Gunicorn options require additional packages. You can use the ``[extra]``
|
|
||||||
syntax to install these at the same time as Gunicorn.
|
|
||||||
|
|
||||||
Most extra packages are needed for alternate worker types. See the
|
|
||||||
`design docs`_ for more information on when you'll want to consider an
|
|
||||||
alternate worker type.
|
|
||||||
|
|
||||||
* ``gunicorn[eventlet]`` - Eventlet-based greenlets workers
|
|
||||||
* ``gunicorn[gevent]`` - Gevent-based greenlets workers
|
|
||||||
* ``gunicorn[gthread]`` - Threaded workers
|
|
||||||
* ``gunicorn[tornado]`` - Tornado-based workers, not recommended
|
|
||||||
|
|
||||||
If you are running more than one instance of Gunicorn, the :ref:`proc-name`
|
|
||||||
setting will help distinguish between them in tools like ``ps`` and ``top``.
|
|
||||||
|
|
||||||
* ``gunicorn[setproctitle]`` - Enables setting the process name
|
|
||||||
|
|
||||||
Multiple extras can be combined, like
|
|
||||||
``pip install gunicorn[gevent,setproctitle]``.
|
|
||||||
|
|
||||||
Debian GNU/Linux
|
|
||||||
================
|
|
||||||
|
|
||||||
If you are using Debian GNU/Linux it is recommended that you use
|
|
||||||
system packages to install Gunicorn except maybe when you want to use
|
|
||||||
different versions of Gunicorn with virtualenv. This has a number of
|
|
||||||
advantages:
|
|
||||||
|
|
||||||
* Zero-effort installation: Automatically starts multiple Gunicorn instances
|
|
||||||
based on configurations defined in ``/etc/gunicorn.d``.
|
|
||||||
|
|
||||||
* Sensible default locations for logs (``/var/log/gunicorn``). Logs
|
|
||||||
can be automatically rotated and compressed using ``logrotate``.
|
|
||||||
|
|
||||||
* Improved security: Can easily run each Gunicorn instance with a dedicated
|
|
||||||
UNIX user/group.
|
|
||||||
|
|
||||||
* Sensible upgrade path: Upgrades to newer versions result in less downtime,
|
|
||||||
handle conflicting changes in configuration options, and can be quickly
|
|
||||||
rolled back in case of incompatibility. The package can also be purged
|
|
||||||
entirely from the system in seconds.
|
|
||||||
|
|
||||||
stable ("buster")
|
|
||||||
------------------
|
|
||||||
|
|
||||||
The version of Gunicorn in the Debian_ "stable" distribution is 19.9.0
|
|
||||||
(December 2020). You can install it using::
|
|
||||||
|
|
||||||
$ sudo apt-get install gunicorn3
|
|
||||||
|
|
||||||
You can also use the most recent version 20.0.4 (December 2020) by using
|
|
||||||
`Debian Backports`_. First, copy the following line to your
|
|
||||||
``/etc/apt/sources.list``::
|
|
||||||
|
|
||||||
deb http://ftp.debian.org/debian buster-backports main
|
|
||||||
|
|
||||||
Then, update your local package lists::
|
|
||||||
|
|
||||||
$ sudo apt-get update
|
|
||||||
|
|
||||||
You can then install the latest version using::
|
|
||||||
|
|
||||||
$ sudo apt-get -t buster-backports install gunicorn
|
|
||||||
|
|
||||||
oldstable ("stretch")
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
While Debian releases newer than Stretch will give you gunicorn with Python 3
|
|
||||||
support no matter if you install the gunicorn or gunicorn3 package for Stretch
|
|
||||||
you specifically have to install gunicorn3 to get Python 3 support.
|
|
||||||
|
|
||||||
The version of Gunicorn in the Debian_ "oldstable" distribution is 19.6.0
|
|
||||||
(December 2020). You can install it using::
|
|
||||||
|
|
||||||
$ sudo apt-get install gunicorn3
|
|
||||||
|
|
||||||
You can also use the most recent version 19.7.1 (December 2020) by using
|
|
||||||
`Debian Backports`_. First, copy the following line to your
|
|
||||||
``/etc/apt/sources.list``::
|
|
||||||
|
|
||||||
deb http://ftp.debian.org/debian stretch-backports main
|
|
||||||
|
|
||||||
Then, update your local package lists::
|
|
||||||
|
|
||||||
$ sudo apt-get update
|
|
||||||
|
|
||||||
You can then install the latest version using::
|
|
||||||
|
|
||||||
$ sudo apt-get -t stretch-backports install gunicorn3
|
|
||||||
|
|
||||||
Testing ("bullseye") / Unstable ("sid")
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
"bullseye" and "sid" contain the latest released version of Gunicorn 20.0.4
|
|
||||||
(December 2020). You can install it in the usual way::
|
|
||||||
|
|
||||||
$ sudo apt-get install gunicorn
|
|
||||||
|
|
||||||
|
|
||||||
Ubuntu
|
|
||||||
======
|
|
||||||
|
|
||||||
Ubuntu_ 20.04 LTS (Focal Fossa) or later contains the Gunicorn package by
|
|
||||||
default 20.0.4 (December 2020) so that you can install it in the usual way::
|
|
||||||
|
|
||||||
$ sudo apt-get update
|
|
||||||
$ sudo apt-get install gunicorn
|
|
||||||
|
|
||||||
|
|
||||||
.. _`design docs`: design.html
|
|
||||||
.. _Eventlet: http://eventlet.net
|
|
||||||
.. _Gevent: http://www.gevent.org/
|
|
||||||
.. _libevent: http://libevent.org/
|
|
||||||
.. _Debian: https://www.debian.org/
|
|
||||||
.. _`Debian Backports`: https://backports.debian.org/
|
|
||||||
.. _Ubuntu: https://www.ubuntu.com/
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
.. _instrumentation:
|
|
||||||
|
|
||||||
===============
|
|
||||||
Instrumentation
|
|
||||||
===============
|
|
||||||
|
|
||||||
.. versionadded:: 19.1
|
|
||||||
|
|
||||||
Gunicorn provides an optional instrumentation of the arbiter and
|
|
||||||
workers using the statsD_ protocol over UDP. Thanks to the
|
|
||||||
``gunicorn.instrument.statsd`` module, Gunicorn becomes a statsD client.
|
|
||||||
The use of UDP cleanly isolates Gunicorn from the receiving end of the statsD
|
|
||||||
metrics so that instrumentation does not cause Gunicorn to be held up by a slow
|
|
||||||
statsD consumer.
|
|
||||||
|
|
||||||
To use statsD, just tell Gunicorn where the statsD server is:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ gunicorn --statsd-host=localhost:8125 --statsd-prefix=service.app ...
|
|
||||||
|
|
||||||
The ``Statsd`` logger overrides ``gunicorn.glogging.Logger`` to track
|
|
||||||
all requests. The following metrics are generated:
|
|
||||||
|
|
||||||
* ``gunicorn.requests``: request rate per second
|
|
||||||
* ``gunicorn.request.duration``: histogram of request duration (in millisecond)
|
|
||||||
* ``gunicorn.workers``: number of workers managed by the arbiter (gauge)
|
|
||||||
* ``gunicorn.log.critical``: rate of critical log messages
|
|
||||||
* ``gunicorn.log.error``: rate of error log messages
|
|
||||||
* ``gunicorn.log.warning``: rate of warning log messages
|
|
||||||
* ``gunicorn.log.exception``: rate of exceptional log messages
|
|
||||||
|
|
||||||
See the statsd-host_ setting for more information.
|
|
||||||
|
|
||||||
.. _statsd-host: settings.html#statsd-host
|
|
||||||
.. _statsD: https://github.com/etsy/statsd
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
=========
|
|
||||||
Changelog
|
|
||||||
=========
|
|
||||||
|
|
||||||
23.0.0 - 2024-08-10
|
|
||||||
===================
|
|
||||||
|
|
||||||
- minor docs fixes (:pr:`3217`, :pr:`3089`, :pr:`3167`)
|
|
||||||
- worker_class parameter accepts a class (:pr:`3079`)
|
|
||||||
- fix deadlock if request terminated during chunked parsing (:pr:`2688`)
|
|
||||||
- permit receiving Transfer-Encodings: compress, deflate, gzip (:pr:`3261`)
|
|
||||||
- permit Transfer-Encoding headers specifying multiple encodings. note: no parameters, still (:pr:`3261`)
|
|
||||||
- sdist generation now explicitly excludes sphinx build folder (:pr:`3257`)
|
|
||||||
- decode bytes-typed status (as can be passed by gevent) as utf-8 instead of raising `TypeError` (:pr:`2336`)
|
|
||||||
- raise correct Exception when encounting invalid chunked requests (:pr:`3258`)
|
|
||||||
- the SCRIPT_NAME and PATH_INFO headers, when received from allowed forwarders, are no longer restricted for containing an underscore (:pr:`3192`)
|
|
||||||
- include IPv6 loopback address ``[::1]`` in default for :ref:`forwarded-allow-ips` and :ref:`proxy-allow-ips` (:pr:`3192`)
|
|
||||||
|
|
||||||
** NOTE **
|
|
||||||
|
|
||||||
- The SCRIPT_NAME change mitigates a regression that appeared first in the 22.0.0 release
|
|
||||||
- Review your :ref:`forwarded-allow-ips` setting if you are still not seeing the SCRIPT_NAME transmitted
|
|
||||||
- Review your :ref:`forwarder-headers` setting if you are missing headers after upgrading from a version prior to 22.0.0
|
|
||||||
|
|
||||||
** Breaking changes **
|
|
||||||
|
|
||||||
- refuse requests where the uri field is empty (:pr:`3255`)
|
|
||||||
- refuse requests with invalid CR/LR/NUL in heade field values (:pr:`3253`)
|
|
||||||
- remove temporary ``--tolerate-dangerous-framing`` switch from 22.0 (:pr:`3260`)
|
|
||||||
- If any of the breaking changes affect you, be aware that now refused requests can post a security problem, especially so in setups involving request pipe-lining and/or proxies.
|
|
||||||
|
|
||||||
22.0.0 - 2024-04-17
|
|
||||||
===================
|
|
||||||
|
|
||||||
- use `utime` to notify workers liveness
|
|
||||||
- migrate setup to pyproject.toml
|
|
||||||
- fix numerous security vulnerabilities in HTTP parser (closing some request smuggling vectors)
|
|
||||||
- parsing additional requests is no longer attempted past unsupported request framing
|
|
||||||
- on HTTP versions < 1.1 support for chunked transfer is refused (only used in exploits)
|
|
||||||
- requests conflicting configured or passed SCRIPT_NAME now produce a verbose error
|
|
||||||
- Trailer fields are no longer inspected for headers indicating secure scheme
|
|
||||||
- support Python 3.12
|
|
||||||
|
|
||||||
** Breaking changes **
|
|
||||||
|
|
||||||
- minimum version is Python 3.7
|
|
||||||
- the limitations on valid characters in the HTTP method have been bounded to Internet Standards
|
|
||||||
- requests specifying unsupported transfer coding (order) are refused by default (rare)
|
|
||||||
- HTTP methods are no longer casefolded by default (IANA method registry contains none affected)
|
|
||||||
- HTTP methods containing the number sign (#) are no longer accepted by default (rare)
|
|
||||||
- HTTP versions < 1.0 or >= 2.0 are no longer accepted by default (rare, only HTTP/1.1 is supported)
|
|
||||||
- HTTP versions consisting of multiple digits or containing a prefix/suffix are no longer accepted
|
|
||||||
- HTTP header field names Gunicorn cannot safely map to variables are silently dropped, as in other software
|
|
||||||
- HTTP headers with empty field name are refused by default (no legitimate use cases, used in exploits)
|
|
||||||
- requests with both Transfer-Encoding and Content-Length are refused by default (such a message might indicate an attempt to perform request smuggling)
|
|
||||||
- empty transfer codings are no longer permitted (reportedly seen with really old & broken proxies)
|
|
||||||
|
|
||||||
|
|
||||||
** SECURITY **
|
|
||||||
|
|
||||||
- fix CVE-2024-1135
|
|
||||||
|
|
||||||
History
|
|
||||||
=======
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:titlesonly:
|
|
||||||
|
|
||||||
2024-news
|
|
||||||
2023-news
|
|
||||||
2021-news
|
|
||||||
2020-news
|
|
||||||
2019-news
|
|
||||||
2018-news
|
|
||||||
2017-news
|
|
||||||
2016-news
|
|
||||||
2015-news
|
|
||||||
2014-news
|
|
||||||
2013-news
|
|
||||||
2012-news
|
|
||||||
2011-news
|
|
||||||
2010-news
|
|
||||||
|
|
||||||
@ -1,184 +0,0 @@
|
|||||||
================
|
|
||||||
Running Gunicorn
|
|
||||||
================
|
|
||||||
|
|
||||||
.. highlight:: bash
|
|
||||||
|
|
||||||
You can run Gunicorn by using commands or integrate with popular frameworks
|
|
||||||
like Django, Pyramid, or TurboGears. For deploying Gunicorn in production see
|
|
||||||
:doc:`deploy`.
|
|
||||||
|
|
||||||
Commands
|
|
||||||
========
|
|
||||||
|
|
||||||
After installing Gunicorn you will have access to the command line script
|
|
||||||
``gunicorn``.
|
|
||||||
|
|
||||||
.. _gunicorn-cmd:
|
|
||||||
|
|
||||||
gunicorn
|
|
||||||
--------
|
|
||||||
|
|
||||||
Basic usage::
|
|
||||||
|
|
||||||
$ gunicorn [OPTIONS] [WSGI_APP]
|
|
||||||
|
|
||||||
Where ``WSGI_APP`` is of the pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``. The
|
|
||||||
module name can be a full dotted path. The variable name refers to a WSGI
|
|
||||||
callable that should be found in the specified module.
|
|
||||||
|
|
||||||
.. versionchanged:: 20.1.0
|
|
||||||
``WSGI_APP`` is optional if it is defined in a :ref:`config` file.
|
|
||||||
|
|
||||||
Example with the test app:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def app(environ, start_response):
|
|
||||||
"""Simplest possible application object"""
|
|
||||||
data = b'Hello, World!\n'
|
|
||||||
status = '200 OK'
|
|
||||||
response_headers = [
|
|
||||||
('Content-type', 'text/plain'),
|
|
||||||
('Content-Length', str(len(data)))
|
|
||||||
]
|
|
||||||
start_response(status, response_headers)
|
|
||||||
return iter([data])
|
|
||||||
|
|
||||||
You can now run the app with the following command:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ gunicorn --workers=2 test:app
|
|
||||||
|
|
||||||
The variable name can also be a function call. In that case the name
|
|
||||||
will be imported from the module, then called to get the application
|
|
||||||
object. This is commonly referred to as the "application factory"
|
|
||||||
pattern.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def create_app():
|
|
||||||
app = FrameworkApp()
|
|
||||||
...
|
|
||||||
return app
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ gunicorn --workers=2 'test:create_app()'
|
|
||||||
|
|
||||||
Positional and keyword arguments can also be passed, but it is
|
|
||||||
recommended to load configuration from environment variables rather than
|
|
||||||
the command line.
|
|
||||||
|
|
||||||
Commonly Used Arguments
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
* ``-c CONFIG, --config=CONFIG`` - Specify a config file in the form
|
|
||||||
``$(PATH)``, ``file:$(PATH)``, or ``python:$(MODULE_NAME)``.
|
|
||||||
* ``-b BIND, --bind=BIND`` - Specify a server socket to bind. Server sockets
|
|
||||||
can be any of ``$(HOST)``, ``$(HOST):$(PORT)``, ``fd://$(FD)``, or
|
|
||||||
``unix:$(PATH)``. An IP is a valid ``$(HOST)``.
|
|
||||||
* ``-w WORKERS, --workers=WORKERS`` - The number of worker processes. This
|
|
||||||
number should generally be between 2-4 workers per core in the server.
|
|
||||||
Check the :ref:`faq` for ideas on tuning this parameter.
|
|
||||||
* ``-k WORKERCLASS, --worker-class=WORKERCLASS`` - The type of worker process
|
|
||||||
to run. You'll definitely want to read the production page for the
|
|
||||||
implications of this parameter. You can set this to ``$(NAME)``
|
|
||||||
where ``$(NAME)`` is one of ``sync``, ``eventlet``, ``gevent``,
|
|
||||||
``tornado``, ``gthread``.
|
|
||||||
``sync`` is the default. See the :ref:`worker-class` documentation for more
|
|
||||||
information.
|
|
||||||
* ``-n APP_NAME, --name=APP_NAME`` - If setproctitle_ is installed you can
|
|
||||||
adjust the name of Gunicorn process as they appear in the process system
|
|
||||||
table (which affects tools like ``ps`` and ``top``).
|
|
||||||
|
|
||||||
Settings can be specified by using environment variable
|
|
||||||
:ref:`GUNICORN_CMD_ARGS <settings>`.
|
|
||||||
|
|
||||||
See :ref:`configuration` and :ref:`settings` for detailed usage.
|
|
||||||
|
|
||||||
.. _setproctitle: https://pypi.python.org/pypi/setproctitle
|
|
||||||
|
|
||||||
Integration
|
|
||||||
===========
|
|
||||||
|
|
||||||
Gunicorn also provides integration for Django and Paste Deploy applications.
|
|
||||||
|
|
||||||
Django
|
|
||||||
------
|
|
||||||
|
|
||||||
Gunicorn will look for a WSGI callable named ``application`` if not specified.
|
|
||||||
So for a typical Django project, invoking Gunicorn would look like::
|
|
||||||
|
|
||||||
$ gunicorn myproject.wsgi
|
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
This requires that your project be on the Python path; the simplest way to
|
|
||||||
ensure that is to run this command from the same directory as your
|
|
||||||
``manage.py`` file.
|
|
||||||
|
|
||||||
You can use the
|
|
||||||
`--env <http://docs.gunicorn.org/en/latest/settings.html#raw-env>`_ option
|
|
||||||
to set the path to load the settings. In case you need it you can also
|
|
||||||
add your application path to ``PYTHONPATH`` using the
|
|
||||||
`--pythonpath <http://docs.gunicorn.org/en/latest/settings.html#pythonpath>`_
|
|
||||||
option::
|
|
||||||
|
|
||||||
$ gunicorn --env DJANGO_SETTINGS_MODULE=myproject.settings myproject.wsgi
|
|
||||||
|
|
||||||
Paste Deployment
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Frameworks such as Pyramid and Turbogears are typically configured using Paste
|
|
||||||
Deployment configuration files. If you would like to use these files with
|
|
||||||
Gunicorn, there are two approaches.
|
|
||||||
|
|
||||||
As a server runner, Gunicorn can serve your application using the commands from
|
|
||||||
your framework, such as ``pserve`` or ``gearbox``. To use Gunicorn with these
|
|
||||||
commands, specify it as a server in your configuration file:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[server:main]
|
|
||||||
use = egg:gunicorn#main
|
|
||||||
host = 127.0.0.1
|
|
||||||
port = 8080
|
|
||||||
workers = 3
|
|
||||||
|
|
||||||
This approach is the quickest way to get started with Gunicorn, but there are
|
|
||||||
some limitations. Gunicorn will have no control over how the application is
|
|
||||||
loaded, so settings such as reload_ will have no effect and Gunicorn will be
|
|
||||||
unable to hot upgrade a running application. Using the daemon_ option may
|
|
||||||
confuse your command line tool. Instead, use the built-in support for these
|
|
||||||
features provided by that tool. For example, run ``pserve --reload`` instead of
|
|
||||||
specifying ``reload = True`` in the server configuration block. For advanced
|
|
||||||
configuration of Gunicorn, such as `Server Hooks`_ specifying a Gunicorn
|
|
||||||
configuration file using the ``config`` key is supported.
|
|
||||||
|
|
||||||
To use the full power of Gunicorn's reloading and hot code upgrades, use the
|
|
||||||
`paste option`_ to run your application instead. When used this way, Gunicorn
|
|
||||||
will use the application defined by the PasteDeploy configuration file, but
|
|
||||||
Gunicorn will not use any server configuration defined in the file. Instead,
|
|
||||||
`configure gunicorn`_.
|
|
||||||
|
|
||||||
For example::
|
|
||||||
|
|
||||||
$ gunicorn --paste development.ini -b :8080 --chdir /path/to/project
|
|
||||||
|
|
||||||
Or use a different application::
|
|
||||||
|
|
||||||
$ gunicorn --paste development.ini#admin -b :8080 --chdir /path/to/project
|
|
||||||
|
|
||||||
With both approaches, Gunicorn will use any loggers section found in Paste
|
|
||||||
Deployment configuration file, unless instructed otherwise by specifying
|
|
||||||
additional `logging settings`_.
|
|
||||||
|
|
||||||
.. _reload: http://docs.gunicorn.org/en/latest/settings.html#reload
|
|
||||||
.. _daemon: http://docs.gunicorn.org/en/latest/settings.html#daemon
|
|
||||||
.. _Server Hooks: http://docs.gunicorn.org/en/latest/settings.html#server-hooks
|
|
||||||
.. _paste option: http://docs.gunicorn.org/en/latest/settings.html#paste
|
|
||||||
.. _configure gunicorn: http://docs.gunicorn.org/en/latest/configure.html
|
|
||||||
.. _logging settings: http://docs.gunicorn.org/en/latest/settings.html#logging
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
.. _signals:
|
|
||||||
|
|
||||||
===============
|
|
||||||
Signal Handling
|
|
||||||
===============
|
|
||||||
|
|
||||||
A brief description of the signals handled by Gunicorn. We also document the
|
|
||||||
signals used internally by Gunicorn to communicate with the workers.
|
|
||||||
|
|
||||||
Master process
|
|
||||||
==============
|
|
||||||
|
|
||||||
- ``QUIT``, ``INT``: Quick shutdown
|
|
||||||
- ``TERM``: Graceful shutdown. Waits for workers to finish their
|
|
||||||
current requests up to the :ref:`graceful-timeout`.
|
|
||||||
- ``HUP``: Reload the configuration, start the new worker processes with a new
|
|
||||||
configuration and gracefully shutdown older workers. If the application is
|
|
||||||
not preloaded (using the :ref:`preload-app` option), Gunicorn will also load
|
|
||||||
the new version of it.
|
|
||||||
- ``TTIN``: Increment the number of processes by one
|
|
||||||
- ``TTOU``: Decrement the number of processes by one
|
|
||||||
- ``USR1``: Reopen the log files
|
|
||||||
- ``USR2``: Upgrade Gunicorn on the fly. A separate ``TERM`` signal should
|
|
||||||
be used to kill the old master process. This signal can also be used to use
|
|
||||||
the new versions of pre-loaded applications. See :ref:`binary-upgrade` for
|
|
||||||
more information.
|
|
||||||
- ``WINCH``: Gracefully shutdown the worker processes when Gunicorn is
|
|
||||||
daemonized.
|
|
||||||
|
|
||||||
Worker process
|
|
||||||
==============
|
|
||||||
|
|
||||||
Sending signals directly to the worker processes should not normally be
|
|
||||||
needed. If the master process is running, any exited worker will be
|
|
||||||
automatically respawned.
|
|
||||||
|
|
||||||
- ``QUIT``, ``INT``: Quick shutdown
|
|
||||||
- ``TERM``: Graceful shutdown
|
|
||||||
- ``USR1``: Reopen the log files
|
|
||||||
|
|
||||||
Reload the configuration
|
|
||||||
========================
|
|
||||||
|
|
||||||
The ``HUP`` signal can be used to reload the Gunicorn configuration on the
|
|
||||||
fly.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
2013-06-29 06:26:55 [20682] [INFO] Handling signal: hup
|
|
||||||
2013-06-29 06:26:55 [20682] [INFO] Hang up: Master
|
|
||||||
2013-06-29 06:26:55 [20703] [INFO] Booting worker with pid: 20703
|
|
||||||
2013-06-29 06:26:55 [20702] [INFO] Booting worker with pid: 20702
|
|
||||||
2013-06-29 06:26:55 [20688] [INFO] Worker exiting (pid: 20688)
|
|
||||||
2013-06-29 06:26:55 [20687] [INFO] Worker exiting (pid: 20687)
|
|
||||||
2013-06-29 06:26:55 [20689] [INFO] Worker exiting (pid: 20689)
|
|
||||||
2013-06-29 06:26:55 [20704] [INFO] Booting worker with pid: 20704
|
|
||||||
|
|
||||||
|
|
||||||
Sending a ``HUP`` signal will reload the configuration, start the new
|
|
||||||
worker processes with a new configuration and gracefully shutdown older
|
|
||||||
workers. If the application is not preloaded (using the :ref:`preload-app`
|
|
||||||
option), Gunicorn will also load the new version of it.
|
|
||||||
|
|
||||||
.. _binary-upgrade:
|
|
||||||
|
|
||||||
Upgrading to a new binary on the fly
|
|
||||||
====================================
|
|
||||||
|
|
||||||
.. versionchanged:: 19.6.0
|
|
||||||
PID file naming format has been changed from ``<name>.pid.oldbin`` to
|
|
||||||
``<name>.pid.2``.
|
|
||||||
|
|
||||||
If you need to replace the Gunicorn binary with a new one (when
|
|
||||||
upgrading to a new version or adding/removing server modules), you can
|
|
||||||
do it without any service downtime - no incoming requests will be
|
|
||||||
lost. Preloaded applications will also be reloaded.
|
|
||||||
|
|
||||||
First, replace the old binary with a new one, then send a ``USR2`` signal to
|
|
||||||
the current master process. It executes a new binary whose PID file is
|
|
||||||
postfixed with ``.2`` (e.g. ``/var/run/gunicorn.pid.2``),
|
|
||||||
which in turn starts a new master process and new worker processes::
|
|
||||||
|
|
||||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
|
||||||
20844 benoitc 20 0 54808 11m 3352 S 0.0 0.1 0:00.36 gunicorn: master [test:app]
|
|
||||||
20849 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
|
||||||
20850 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
|
||||||
20851 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
|
||||||
20854 benoitc 20 0 55748 12m 3348 S 0.0 0.2 0:00.35 gunicorn: master [test:app]
|
|
||||||
20859 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
|
||||||
20860 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.00 gunicorn: worker [test:app]
|
|
||||||
20861 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
|
||||||
|
|
||||||
At this point, two instances of Gunicorn are running, handling the
|
|
||||||
incoming requests together. To phase the old instance out, you have to
|
|
||||||
send a ``WINCH`` signal to the old master process, and its worker
|
|
||||||
processes will start to gracefully shut down.
|
|
||||||
|
|
||||||
At this point you can still revert to the old process since it hasn't closed
|
|
||||||
its listen sockets yet, by following these steps:
|
|
||||||
|
|
||||||
- Send a ``HUP`` signal to the old master process - it will start the worker
|
|
||||||
processes without reloading a configuration file
|
|
||||||
- Send a ``TERM`` signal to the new master process to gracefully shut down its
|
|
||||||
worker processes
|
|
||||||
- Send a ``QUIT`` signal to the new master process to force it quit
|
|
||||||
|
|
||||||
If for some reason the new worker processes do not quit, send a ``KILL`` signal
|
|
||||||
to them after the new master process quits, and everything will back to exactly
|
|
||||||
as before the upgrade attempt.
|
|
||||||
|
|
||||||
If the update is successful and you want to keep the new master process, send a
|
|
||||||
``TERM`` signal to the old master process to leave only the new server
|
|
||||||
running::
|
|
||||||
|
|
||||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
|
||||||
20854 benoitc 20 0 55748 12m 3348 S 0.0 0.2 0:00.45 gunicorn: master [test:app]
|
|
||||||
20859 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
|
||||||
20860 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
|
||||||
20861 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
version_info = (23, 0, 0)
|
version_info = (24, 0, 0)
|
||||||
__version__ = ".".join([str(v) for v in version_info])
|
__version__ = ".".join([str(v) for v in version_info])
|
||||||
SERVER = "gunicorn"
|
SERVER = "gunicorn"
|
||||||
SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__)
|
SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__)
|
||||||
|
|||||||