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.
|
||||
# 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])
|
||||
SERVER = "gunicorn"
|
||||
SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__)
|
||||
|
||||